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"
22*17bac89eSShawn McCarney #include "mock_action.hpp"
23525e20c9SShawn McCarney #include "mock_journal.hpp"
24*17bac89eSShawn McCarney #include "mock_sensors.hpp"
2523243f84SBob King #include "mock_services.hpp"
26050531f5SShawn McCarney #include "mocked_i2c_interface.hpp"
27525e20c9SShawn McCarney #include "presence_detection.hpp"
28525e20c9SShawn McCarney #include "rail.hpp"
29525e20c9SShawn McCarney #include "rule.hpp"
30*17bac89eSShawn McCarney #include "sensor_monitoring.hpp"
312f9e14f6SShawn McCarney #include "sensors.hpp"
32525e20c9SShawn McCarney #include "system.hpp"
338a3afd70SShawn McCarney #include "test_utils.hpp"
348a3afd70SShawn McCarney 
358a3afd70SShawn McCarney #include <memory>
368a3afd70SShawn McCarney #include <stdexcept>
37525e20c9SShawn McCarney #include <string>
388a3afd70SShawn McCarney #include <utility>
398a3afd70SShawn McCarney #include <vector>
408a3afd70SShawn McCarney 
41a2c81a61SBob King #include <gmock/gmock.h>
428a3afd70SShawn McCarney #include <gtest/gtest.h>
438a3afd70SShawn McCarney 
448a3afd70SShawn McCarney using namespace phosphor::power::regulators;
458a3afd70SShawn McCarney using namespace phosphor::power::regulators::test_utils;
468a3afd70SShawn McCarney 
47a2c81a61SBob King using ::testing::A;
48050531f5SShawn McCarney using ::testing::Return;
49a2c81a61SBob King using ::testing::TypedEq;
50050531f5SShawn McCarney 
51cb3f6a63SShawn McCarney // Default chassis inventory path
52cb3f6a63SShawn McCarney static const std::string defaultInventoryPath{
53cb3f6a63SShawn McCarney     "/xyz/openbmc_project/inventory/system/chassis"};
54cb3f6a63SShawn McCarney 
558a3afd70SShawn McCarney TEST(ChassisTests, Constructor)
568a3afd70SShawn McCarney {
578a3afd70SShawn McCarney     // Test where works: Only required parameters are specified
588a3afd70SShawn McCarney     {
59cb3f6a63SShawn McCarney         Chassis chassis{2, defaultInventoryPath};
608a3afd70SShawn McCarney         EXPECT_EQ(chassis.getNumber(), 2);
61cb3f6a63SShawn McCarney         EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
628a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 0);
638a3afd70SShawn McCarney     }
648a3afd70SShawn McCarney 
658a3afd70SShawn McCarney     // Test where works: All parameters are specified
668a3afd70SShawn McCarney     {
678a3afd70SShawn McCarney         // Create vector of Device objects
688a3afd70SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
69db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg1"));
70db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg2"));
718a3afd70SShawn McCarney 
728a3afd70SShawn McCarney         // Create Chassis
73cb3f6a63SShawn McCarney         Chassis chassis{1, defaultInventoryPath, std::move(devices)};
748a3afd70SShawn McCarney         EXPECT_EQ(chassis.getNumber(), 1);
75cb3f6a63SShawn McCarney         EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
768a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 2);
778a3afd70SShawn McCarney     }
788a3afd70SShawn McCarney 
798a3afd70SShawn McCarney     // Test where fails: Invalid chassis number < 1
808a3afd70SShawn McCarney     try
818a3afd70SShawn McCarney     {
82cb3f6a63SShawn McCarney         Chassis chassis{0, defaultInventoryPath};
838a3afd70SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
848a3afd70SShawn McCarney     }
858a3afd70SShawn McCarney     catch (const std::invalid_argument& e)
868a3afd70SShawn McCarney     {
878a3afd70SShawn McCarney         EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
888a3afd70SShawn McCarney     }
898a3afd70SShawn McCarney     catch (...)
908a3afd70SShawn McCarney     {
918a3afd70SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
928a3afd70SShawn McCarney     }
938a3afd70SShawn McCarney }
948a3afd70SShawn McCarney 
95db0b833cSShawn McCarney TEST(ChassisTests, AddToIDMap)
96db0b833cSShawn McCarney {
97db0b833cSShawn McCarney     // Create vector of Device objects
98db0b833cSShawn McCarney     std::vector<std::unique_ptr<Device>> devices{};
99db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg1", {"rail1"}));
100db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
101db0b833cSShawn McCarney     devices.emplace_back(createDevice("reg3"));
102db0b833cSShawn McCarney 
103db0b833cSShawn McCarney     // Create Chassis
104cb3f6a63SShawn McCarney     Chassis chassis{1, defaultInventoryPath, std::move(devices)};
105db0b833cSShawn McCarney 
106db0b833cSShawn McCarney     // Add Device and Rail objects within the Chassis to an IDMap
107db0b833cSShawn McCarney     IDMap idMap{};
108db0b833cSShawn McCarney     chassis.addToIDMap(idMap);
109db0b833cSShawn McCarney 
110db0b833cSShawn McCarney     // Verify all Devices are in the IDMap
111db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg1"));
112db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg2"));
113db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getDevice("reg3"));
114db0b833cSShawn McCarney     EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
115db0b833cSShawn McCarney 
116db0b833cSShawn McCarney     // Verify all Rails are in the IDMap
117db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail1"));
118db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail2a"));
119db0b833cSShawn McCarney     EXPECT_NO_THROW(idMap.getRail("rail2b"));
120db0b833cSShawn McCarney     EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
121db0b833cSShawn McCarney }
122db0b833cSShawn McCarney 
1239bd94d36SShawn McCarney TEST(ChassisTests, ClearCache)
1249bd94d36SShawn McCarney {
1259bd94d36SShawn McCarney     // Create PresenceDetection
1269bd94d36SShawn McCarney     std::vector<std::unique_ptr<Action>> actions{};
1279bd94d36SShawn McCarney     std::unique_ptr<PresenceDetection> presenceDetection =
1289bd94d36SShawn McCarney         std::make_unique<PresenceDetection>(std::move(actions));
1299bd94d36SShawn McCarney     PresenceDetection* presenceDetectionPtr = presenceDetection.get();
1309bd94d36SShawn McCarney 
1319bd94d36SShawn McCarney     // Create Device that contains PresenceDetection
1329bd94d36SShawn McCarney     std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
1339bd94d36SShawn McCarney     std::unique_ptr<Device> device = std::make_unique<Device>(
1349bd94d36SShawn McCarney         "reg1", true,
1359bd94d36SShawn McCarney         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
1369bd94d36SShawn McCarney         std::move(i2cInterface), std::move(presenceDetection));
1379bd94d36SShawn McCarney     Device* devicePtr = device.get();
1389bd94d36SShawn McCarney 
1399bd94d36SShawn McCarney     // Create Chassis that contains Device
1409bd94d36SShawn McCarney     std::vector<std::unique_ptr<Device>> devices{};
1419bd94d36SShawn McCarney     devices.emplace_back(std::move(device));
1429bd94d36SShawn McCarney     std::unique_ptr<Chassis> chassis =
143cb3f6a63SShawn McCarney         std::make_unique<Chassis>(1, defaultInventoryPath, std::move(devices));
1449bd94d36SShawn McCarney     Chassis* chassisPtr = chassis.get();
1459bd94d36SShawn McCarney 
1469bd94d36SShawn McCarney     // Create System that contains Chassis
1479bd94d36SShawn McCarney     std::vector<std::unique_ptr<Rule>> rules{};
1489bd94d36SShawn McCarney     std::vector<std::unique_ptr<Chassis>> chassisVec{};
1499bd94d36SShawn McCarney     chassisVec.emplace_back(std::move(chassis));
1509bd94d36SShawn McCarney     System system{std::move(rules), std::move(chassisVec)};
1519bd94d36SShawn McCarney 
1529bd94d36SShawn McCarney     // Cache presence value in PresenceDetection
1539bd94d36SShawn McCarney     MockServices services{};
1549bd94d36SShawn McCarney     presenceDetectionPtr->execute(services, system, *chassisPtr, *devicePtr);
1559bd94d36SShawn McCarney     EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
1569bd94d36SShawn McCarney 
1579bd94d36SShawn McCarney     // Clear cached data in Chassis
1589bd94d36SShawn McCarney     chassisPtr->clearCache();
1599bd94d36SShawn McCarney 
1609bd94d36SShawn McCarney     // Verify presence value no longer cached in PresenceDetection
1619bd94d36SShawn McCarney     EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
1629bd94d36SShawn McCarney }
1639bd94d36SShawn McCarney 
164050531f5SShawn McCarney TEST(ChassisTests, CloseDevices)
165050531f5SShawn McCarney {
166050531f5SShawn McCarney     // Test where no devices were specified in constructor
167050531f5SShawn McCarney     {
168d692d6dfSBob King         // Create mock services.  Expect logDebug() to be called.
169d692d6dfSBob King         MockServices services{};
170d692d6dfSBob King         MockJournal& journal = services.getMockJournal();
171d692d6dfSBob King         EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1);
172d692d6dfSBob King 
173050531f5SShawn McCarney         // Create Chassis
174cb3f6a63SShawn McCarney         Chassis chassis{2, defaultInventoryPath};
175050531f5SShawn McCarney 
176050531f5SShawn McCarney         // Call closeDevices()
177d692d6dfSBob King         chassis.closeDevices(services);
178050531f5SShawn McCarney     }
179050531f5SShawn McCarney 
180050531f5SShawn McCarney     // Test where devices were specified in constructor
181050531f5SShawn McCarney     {
182050531f5SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
183050531f5SShawn McCarney 
184d692d6dfSBob King         // Create mock services.  Expect logDebug() to be called.
185d692d6dfSBob King         MockServices services{};
186d692d6dfSBob King         MockJournal& journal = services.getMockJournal();
187d692d6dfSBob King         EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
188d692d6dfSBob King 
189050531f5SShawn McCarney         // Create Device vdd0_reg
190050531f5SShawn McCarney         {
191050531f5SShawn McCarney             // Create mock I2CInterface: isOpen() and close() should be called
192050531f5SShawn McCarney             std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
193050531f5SShawn McCarney                 std::make_unique<i2c::MockedI2CInterface>();
194050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
195050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, close).Times(1);
196050531f5SShawn McCarney 
197050531f5SShawn McCarney             // Create Device
198a76898f1SBob King             std::unique_ptr<Device> device =
199a76898f1SBob King                 std::make_unique<Device>("vdd0_reg", true,
200a76898f1SBob King                                          "/xyz/openbmc_project/inventory/"
201a76898f1SBob King                                          "system/chassis/motherboard/vdd0_reg",
202050531f5SShawn McCarney                                          std::move(i2cInterface));
203050531f5SShawn McCarney             devices.emplace_back(std::move(device));
204050531f5SShawn McCarney         }
205050531f5SShawn McCarney 
206050531f5SShawn McCarney         // Create Device vdd1_reg
207050531f5SShawn McCarney         {
208050531f5SShawn McCarney             // Create mock I2CInterface: isOpen() and close() should be called
209050531f5SShawn McCarney             std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
210050531f5SShawn McCarney                 std::make_unique<i2c::MockedI2CInterface>();
211050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
212050531f5SShawn McCarney             EXPECT_CALL(*i2cInterface, close).Times(1);
213050531f5SShawn McCarney 
214050531f5SShawn McCarney             // Create Device
215a76898f1SBob King             std::unique_ptr<Device> device =
216a76898f1SBob King                 std::make_unique<Device>("vdd1_reg", true,
217a76898f1SBob King                                          "/xyz/openbmc_project/inventory/"
218a76898f1SBob King                                          "system/chassis/motherboard/vdd1_reg",
219050531f5SShawn McCarney                                          std::move(i2cInterface));
220050531f5SShawn McCarney             devices.emplace_back(std::move(device));
221050531f5SShawn McCarney         }
222050531f5SShawn McCarney 
223050531f5SShawn McCarney         // Create Chassis
224cb3f6a63SShawn McCarney         Chassis chassis{1, defaultInventoryPath, std::move(devices)};
225050531f5SShawn McCarney 
226050531f5SShawn McCarney         // Call closeDevices()
227d692d6dfSBob King         chassis.closeDevices(services);
228050531f5SShawn McCarney     }
229050531f5SShawn McCarney }
230050531f5SShawn McCarney 
231525e20c9SShawn McCarney TEST(ChassisTests, Configure)
232525e20c9SShawn McCarney {
233525e20c9SShawn McCarney     // Test where no devices were specified in constructor
234525e20c9SShawn McCarney     {
2355cfe5103SBob King         // Create mock services.  Expect logInfo() to be called.
23623243f84SBob King         MockServices services{};
2375cfe5103SBob King         MockJournal& journal = services.getMockJournal();
2385cfe5103SBob King         EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
2395cfe5103SBob King         EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
2405cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
24123243f84SBob King 
242525e20c9SShawn McCarney         // Create Chassis
243cb3f6a63SShawn McCarney         std::unique_ptr<Chassis> chassis =
244cb3f6a63SShawn McCarney             std::make_unique<Chassis>(1, defaultInventoryPath);
245525e20c9SShawn McCarney         Chassis* chassisPtr = chassis.get();
246525e20c9SShawn McCarney 
247525e20c9SShawn McCarney         // Create System that contains Chassis
248525e20c9SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
249525e20c9SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
250525e20c9SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
251525e20c9SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
252525e20c9SShawn McCarney 
253525e20c9SShawn McCarney         // Call configure()
25423243f84SBob King         chassisPtr->configure(services, system);
255525e20c9SShawn McCarney     }
256525e20c9SShawn McCarney 
257525e20c9SShawn McCarney     // Test where devices were specified in constructor
258525e20c9SShawn McCarney     {
259525e20c9SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
260525e20c9SShawn McCarney 
2615cfe5103SBob King         // Create mock services.  Expect logInfo() and logDebug() to be called.
2625cfe5103SBob King         MockServices services{};
2635cfe5103SBob King         MockJournal& journal = services.getMockJournal();
2645cfe5103SBob King         EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1);
2655cfe5103SBob King         EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000"))
2665cfe5103SBob King             .Times(1);
2675cfe5103SBob King         EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000"))
2685cfe5103SBob King             .Times(1);
2695cfe5103SBob King         EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
2705cfe5103SBob King 
271525e20c9SShawn McCarney         // Create Device vdd0_reg
272525e20c9SShawn McCarney         {
273525e20c9SShawn McCarney             // Create Configuration
274525e20c9SShawn McCarney             std::vector<std::unique_ptr<Action>> actions{};
275525e20c9SShawn McCarney             std::unique_ptr<Configuration> configuration =
276525e20c9SShawn McCarney                 std::make_unique<Configuration>(1.3, std::move(actions));
277525e20c9SShawn McCarney 
278525e20c9SShawn McCarney             // Create Device
279525e20c9SShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
280525e20c9SShawn McCarney                 createI2CInterface();
281525e20c9SShawn McCarney             std::unique_ptr<PresenceDetection> presenceDetection{};
282525e20c9SShawn McCarney             std::unique_ptr<Device> device = std::make_unique<Device>(
283a76898f1SBob King                 "vdd0_reg", true,
284a76898f1SBob King                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
285a76898f1SBob King                 "vdd0_reg",
286525e20c9SShawn McCarney                 std::move(i2cInterface), std::move(presenceDetection),
287525e20c9SShawn McCarney                 std::move(configuration));
288525e20c9SShawn McCarney             devices.emplace_back(std::move(device));
289525e20c9SShawn McCarney         }
290525e20c9SShawn McCarney 
291525e20c9SShawn McCarney         // Create Device vdd1_reg
292525e20c9SShawn McCarney         {
293525e20c9SShawn McCarney             // Create Configuration
294525e20c9SShawn McCarney             std::vector<std::unique_ptr<Action>> actions{};
295525e20c9SShawn McCarney             std::unique_ptr<Configuration> configuration =
296525e20c9SShawn McCarney                 std::make_unique<Configuration>(1.2, std::move(actions));
297525e20c9SShawn McCarney 
298525e20c9SShawn McCarney             // Create Device
299525e20c9SShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
300525e20c9SShawn McCarney                 createI2CInterface();
301525e20c9SShawn McCarney             std::unique_ptr<PresenceDetection> presenceDetection{};
302525e20c9SShawn McCarney             std::unique_ptr<Device> device = std::make_unique<Device>(
303a76898f1SBob King                 "vdd1_reg", true,
304a76898f1SBob King                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
305a76898f1SBob King                 "vdd1_reg",
306525e20c9SShawn McCarney                 std::move(i2cInterface), std::move(presenceDetection),
307525e20c9SShawn McCarney                 std::move(configuration));
308525e20c9SShawn McCarney             devices.emplace_back(std::move(device));
309525e20c9SShawn McCarney         }
310525e20c9SShawn McCarney 
311525e20c9SShawn McCarney         // Create Chassis
312cb3f6a63SShawn McCarney         std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
313cb3f6a63SShawn McCarney             2, defaultInventoryPath, std::move(devices));
314525e20c9SShawn McCarney         Chassis* chassisPtr = chassis.get();
315525e20c9SShawn McCarney 
316525e20c9SShawn McCarney         // Create System that contains Chassis
317525e20c9SShawn McCarney         std::vector<std::unique_ptr<Rule>> rules{};
318525e20c9SShawn McCarney         std::vector<std::unique_ptr<Chassis>> chassisVec{};
319525e20c9SShawn McCarney         chassisVec.emplace_back(std::move(chassis));
320525e20c9SShawn McCarney         System system{std::move(rules), std::move(chassisVec)};
321525e20c9SShawn McCarney 
322525e20c9SShawn McCarney         // Call configure()
32323243f84SBob King         chassisPtr->configure(services, system);
324525e20c9SShawn McCarney     }
325525e20c9SShawn McCarney }
326525e20c9SShawn McCarney 
3278a3afd70SShawn McCarney TEST(ChassisTests, GetDevices)
3288a3afd70SShawn McCarney {
3298a3afd70SShawn McCarney     // Test where no devices were specified in constructor
3308a3afd70SShawn McCarney     {
331cb3f6a63SShawn McCarney         Chassis chassis{2, defaultInventoryPath};
3328a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 0);
3338a3afd70SShawn McCarney     }
3348a3afd70SShawn McCarney 
3358a3afd70SShawn McCarney     // Test where devices were specified in constructor
3368a3afd70SShawn McCarney     {
3378a3afd70SShawn McCarney         // Create vector of Device objects
3388a3afd70SShawn McCarney         std::vector<std::unique_ptr<Device>> devices{};
339db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg1"));
340db0b833cSShawn McCarney         devices.emplace_back(createDevice("vdd_reg2"));
3418a3afd70SShawn McCarney 
3428a3afd70SShawn McCarney         // Create Chassis
343cb3f6a63SShawn McCarney         Chassis chassis{1, defaultInventoryPath, std::move(devices)};
3448a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices().size(), 2);
3458a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
3468a3afd70SShawn McCarney         EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
3478a3afd70SShawn McCarney     }
3488a3afd70SShawn McCarney }
3498a3afd70SShawn McCarney 
350cb3f6a63SShawn McCarney TEST(ChassisTests, GetInventoryPath)
351cb3f6a63SShawn McCarney {
352cb3f6a63SShawn McCarney     Chassis chassis{3, defaultInventoryPath};
353cb3f6a63SShawn McCarney     EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
354cb3f6a63SShawn McCarney }
355cb3f6a63SShawn McCarney 
3568a3afd70SShawn McCarney TEST(ChassisTests, GetNumber)
3578a3afd70SShawn McCarney {
358cb3f6a63SShawn McCarney     Chassis chassis{3, defaultInventoryPath};
3598a3afd70SShawn McCarney     EXPECT_EQ(chassis.getNumber(), 3);
3608a3afd70SShawn McCarney }
361a2c81a61SBob King 
362a2c81a61SBob King TEST(ChassisTests, MonitorSensors)
363a2c81a61SBob King {
364a2c81a61SBob King     // Test where no devices were specified in constructor
365a2c81a61SBob King     {
366*17bac89eSShawn McCarney         // Create mock services.  No Sensors methods should be called.
3678a55292dSBob King         MockServices services{};
368*17bac89eSShawn McCarney         MockSensors& sensors = services.getMockSensors();
369*17bac89eSShawn McCarney         EXPECT_CALL(sensors, startRail).Times(0);
370*17bac89eSShawn McCarney         EXPECT_CALL(sensors, setValue).Times(0);
371*17bac89eSShawn McCarney         EXPECT_CALL(sensors, endRail).Times(0);
3728a55292dSBob King 
373a2c81a61SBob King         // Create Chassis
374*17bac89eSShawn McCarney         std::unique_ptr<Chassis> chassis =
375*17bac89eSShawn McCarney             std::make_unique<Chassis>(1, defaultInventoryPath);
376a2c81a61SBob King         Chassis* chassisPtr = chassis.get();
377a2c81a61SBob King 
378a2c81a61SBob King         // Create System that contains Chassis
379a2c81a61SBob King         std::vector<std::unique_ptr<Rule>> rules{};
380a2c81a61SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
381a2c81a61SBob King         chassisVec.emplace_back(std::move(chassis));
382a2c81a61SBob King         System system{std::move(rules), std::move(chassisVec)};
383a2c81a61SBob King 
384a2c81a61SBob King         // Call monitorSensors().  Should do nothing.
3858a55292dSBob King         chassisPtr->monitorSensors(services, system);
386a2c81a61SBob King     }
387a2c81a61SBob King 
388a2c81a61SBob King     // Test where devices were specified in constructor
389a2c81a61SBob King     {
390*17bac89eSShawn McCarney         // Create mock services.  Set Sensors service expectations.
3918a55292dSBob King         MockServices services{};
392*17bac89eSShawn McCarney         MockSensors& sensors = services.getMockSensors();
393*17bac89eSShawn McCarney         EXPECT_CALL(sensors, startRail("vdd0",
394*17bac89eSShawn McCarney                                        "/xyz/openbmc_project/inventory/system/"
395*17bac89eSShawn McCarney                                        "chassis/motherboard/vdd0_reg",
396*17bac89eSShawn McCarney                                        defaultInventoryPath))
397*17bac89eSShawn McCarney             .Times(1);
398*17bac89eSShawn McCarney         EXPECT_CALL(sensors, startRail("vdd1",
399*17bac89eSShawn McCarney                                        "/xyz/openbmc_project/inventory/system/"
400*17bac89eSShawn McCarney                                        "chassis/motherboard/vdd1_reg",
401*17bac89eSShawn McCarney                                        defaultInventoryPath))
402*17bac89eSShawn McCarney             .Times(1);
403*17bac89eSShawn McCarney         EXPECT_CALL(sensors, setValue).Times(0);
404*17bac89eSShawn McCarney         EXPECT_CALL(sensors, endRail(false)).Times(2);
4058a55292dSBob King 
406a2c81a61SBob King         std::vector<std::unique_ptr<Device>> devices{};
407a2c81a61SBob King 
408*17bac89eSShawn McCarney         // Create Device vdd0_reg
409*17bac89eSShawn McCarney         {
410*17bac89eSShawn McCarney             // Create SensorMonitoring for Rail
411*17bac89eSShawn McCarney             std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
412*17bac89eSShawn McCarney             EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
413a2c81a61SBob King             std::vector<std::unique_ptr<Action>> actions{};
414a2c81a61SBob King             actions.emplace_back(std::move(action));
415a2c81a61SBob King             std::unique_ptr<SensorMonitoring> sensorMonitoring =
416a2c81a61SBob King                 std::make_unique<SensorMonitoring>(std::move(actions));
417a2c81a61SBob King 
418a2c81a61SBob King             // Create Rail
419a2c81a61SBob King             std::unique_ptr<Configuration> configuration{};
420a2c81a61SBob King             std::unique_ptr<Rail> rail = std::make_unique<Rail>(
421a2c81a61SBob King                 "vdd0", std::move(configuration), std::move(sensorMonitoring));
422a2c81a61SBob King 
423a2c81a61SBob King             // Create Device
424*17bac89eSShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
425*17bac89eSShawn McCarney                 createI2CInterface();
426a2c81a61SBob King             std::unique_ptr<PresenceDetection> presenceDetection{};
427a2c81a61SBob King             std::unique_ptr<Configuration> deviceConfiguration{};
428*17bac89eSShawn McCarney             std::vector<std::unique_ptr<Rail>> rails{};
429*17bac89eSShawn McCarney             rails.emplace_back(std::move(rail));
430a2c81a61SBob King             std::unique_ptr<Device> device = std::make_unique<Device>(
431*17bac89eSShawn McCarney                 "vdd0_reg", true,
432*17bac89eSShawn McCarney                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
433*17bac89eSShawn McCarney                 "vdd0_reg",
434a2c81a61SBob King                 std::move(i2cInterface), std::move(presenceDetection),
435a2c81a61SBob King                 std::move(deviceConfiguration), std::move(rails));
436a2c81a61SBob King             devices.emplace_back(std::move(device));
437*17bac89eSShawn McCarney         }
438*17bac89eSShawn McCarney 
439*17bac89eSShawn McCarney         // Create Device vdd1_reg
440*17bac89eSShawn McCarney         {
441*17bac89eSShawn McCarney             // Create SensorMonitoring for Rail
442*17bac89eSShawn McCarney             std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
443*17bac89eSShawn McCarney             EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
444*17bac89eSShawn McCarney             std::vector<std::unique_ptr<Action>> actions{};
445*17bac89eSShawn McCarney             actions.emplace_back(std::move(action));
446*17bac89eSShawn McCarney             std::unique_ptr<SensorMonitoring> sensorMonitoring =
447*17bac89eSShawn McCarney                 std::make_unique<SensorMonitoring>(std::move(actions));
448*17bac89eSShawn McCarney 
449*17bac89eSShawn McCarney             // Create Rail
450*17bac89eSShawn McCarney             std::unique_ptr<Configuration> configuration{};
451*17bac89eSShawn McCarney             std::unique_ptr<Rail> rail = std::make_unique<Rail>(
452*17bac89eSShawn McCarney                 "vdd1", std::move(configuration), std::move(sensorMonitoring));
453*17bac89eSShawn McCarney 
454*17bac89eSShawn McCarney             // Create Device
455*17bac89eSShawn McCarney             std::unique_ptr<i2c::I2CInterface> i2cInterface =
456*17bac89eSShawn McCarney                 createI2CInterface();
457*17bac89eSShawn McCarney             std::unique_ptr<PresenceDetection> presenceDetection{};
458*17bac89eSShawn McCarney             std::unique_ptr<Configuration> deviceConfiguration{};
459*17bac89eSShawn McCarney             std::vector<std::unique_ptr<Rail>> rails{};
460*17bac89eSShawn McCarney             rails.emplace_back(std::move(rail));
461*17bac89eSShawn McCarney             std::unique_ptr<Device> device = std::make_unique<Device>(
462*17bac89eSShawn McCarney                 "vdd1_reg", true,
463*17bac89eSShawn McCarney                 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
464*17bac89eSShawn McCarney                 "vdd1_reg",
465*17bac89eSShawn McCarney                 std::move(i2cInterface), std::move(presenceDetection),
466*17bac89eSShawn McCarney                 std::move(deviceConfiguration), std::move(rails));
467*17bac89eSShawn McCarney             devices.emplace_back(std::move(device));
468*17bac89eSShawn McCarney         }
469*17bac89eSShawn McCarney 
470*17bac89eSShawn McCarney         // Create Chassis that contains Devices
471cb3f6a63SShawn McCarney         std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
472*17bac89eSShawn McCarney             2, defaultInventoryPath, std::move(devices));
473a2c81a61SBob King         Chassis* chassisPtr = chassis.get();
474a2c81a61SBob King 
475a2c81a61SBob King         // Create System that contains Chassis
476a2c81a61SBob King         std::vector<std::unique_ptr<Rule>> rules{};
477a2c81a61SBob King         std::vector<std::unique_ptr<Chassis>> chassisVec{};
478a2c81a61SBob King         chassisVec.emplace_back(std::move(chassis));
479a2c81a61SBob King         System system{std::move(rules), std::move(chassisVec)};
480a2c81a61SBob King 
481a2c81a61SBob King         // Call monitorSensors()
4828a55292dSBob King         chassisPtr->monitorSensors(services, system);
483a2c81a61SBob King     }
484a2c81a61SBob King }
485