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" 2217bac89eSShawn McCarney #include "mock_action.hpp" 239f3e54e6SShawn McCarney #include "mock_error_logging.hpp" 24525e20c9SShawn McCarney #include "mock_journal.hpp" 2517bac89eSShawn McCarney #include "mock_sensors.hpp" 2623243f84SBob King #include "mock_services.hpp" 27050531f5SShawn McCarney #include "mocked_i2c_interface.hpp" 2832252599SShawn McCarney #include "phase_fault_detection.hpp" 29525e20c9SShawn McCarney #include "presence_detection.hpp" 30525e20c9SShawn McCarney #include "rail.hpp" 31525e20c9SShawn McCarney #include "rule.hpp" 3217bac89eSShawn McCarney #include "sensor_monitoring.hpp" 332f9e14f6SShawn McCarney #include "sensors.hpp" 34525e20c9SShawn McCarney #include "system.hpp" 359f3e54e6SShawn McCarney #include "test_sdbus_error.hpp" 368a3afd70SShawn McCarney #include "test_utils.hpp" 378a3afd70SShawn McCarney 388a3afd70SShawn McCarney #include <memory> 398a3afd70SShawn McCarney #include <stdexcept> 40525e20c9SShawn McCarney #include <string> 418a3afd70SShawn McCarney #include <utility> 428a3afd70SShawn McCarney #include <vector> 438a3afd70SShawn McCarney 44a2c81a61SBob King #include <gmock/gmock.h> 458a3afd70SShawn McCarney #include <gtest/gtest.h> 468a3afd70SShawn McCarney 478a3afd70SShawn McCarney using namespace phosphor::power::regulators; 488a3afd70SShawn McCarney using namespace phosphor::power::regulators::test_utils; 498a3afd70SShawn McCarney 50a2c81a61SBob King using ::testing::A; 51050531f5SShawn McCarney using ::testing::Return; 529f3e54e6SShawn McCarney using ::testing::Throw; 53a2c81a61SBob King using ::testing::TypedEq; 54050531f5SShawn McCarney 55*83058606SShawn McCarney class ChassisTests : public ::testing::Test 56*83058606SShawn McCarney { 57*83058606SShawn McCarney public: 58*83058606SShawn McCarney /** 59*83058606SShawn McCarney * Constructor. 60*83058606SShawn McCarney * 61*83058606SShawn McCarney * Creates the System object needed for calling some Chassis methods. 62*83058606SShawn McCarney */ 63*83058606SShawn McCarney ChassisTests() : ::testing::Test{} 64*83058606SShawn McCarney { 65*83058606SShawn McCarney std::vector<std::unique_ptr<Rule>> rules{}; 66*83058606SShawn McCarney std::vector<std::unique_ptr<Chassis>> chassis{}; 67*83058606SShawn McCarney system = std::make_unique<System>(std::move(rules), std::move(chassis)); 68*83058606SShawn McCarney } 69*83058606SShawn McCarney 70*83058606SShawn McCarney protected: 71*83058606SShawn McCarney const std::string defaultInventoryPath{ 72cb3f6a63SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis"}; 73cb3f6a63SShawn McCarney 74*83058606SShawn McCarney std::unique_ptr<System> system{}; 75*83058606SShawn McCarney }; 76*83058606SShawn McCarney 77*83058606SShawn McCarney TEST_F(ChassisTests, Constructor) 788a3afd70SShawn McCarney { 798a3afd70SShawn McCarney // Test where works: Only required parameters are specified 808a3afd70SShawn McCarney { 81cb3f6a63SShawn McCarney Chassis chassis{2, defaultInventoryPath}; 828a3afd70SShawn McCarney EXPECT_EQ(chassis.getNumber(), 2); 83cb3f6a63SShawn McCarney EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath); 848a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices().size(), 0); 858a3afd70SShawn McCarney } 868a3afd70SShawn McCarney 878a3afd70SShawn McCarney // Test where works: All parameters are specified 888a3afd70SShawn McCarney { 898a3afd70SShawn McCarney // Create vector of Device objects 908a3afd70SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 91db0b833cSShawn McCarney devices.emplace_back(createDevice("vdd_reg1")); 92db0b833cSShawn McCarney devices.emplace_back(createDevice("vdd_reg2")); 938a3afd70SShawn McCarney 948a3afd70SShawn McCarney // Create Chassis 95cb3f6a63SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 968a3afd70SShawn McCarney EXPECT_EQ(chassis.getNumber(), 1); 97cb3f6a63SShawn McCarney EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath); 988a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices().size(), 2); 998a3afd70SShawn McCarney } 1008a3afd70SShawn McCarney 1018a3afd70SShawn McCarney // Test where fails: Invalid chassis number < 1 1028a3afd70SShawn McCarney try 1038a3afd70SShawn McCarney { 104cb3f6a63SShawn McCarney Chassis chassis{0, defaultInventoryPath}; 1058a3afd70SShawn McCarney ADD_FAILURE() << "Should not have reached this line."; 1068a3afd70SShawn McCarney } 1078a3afd70SShawn McCarney catch (const std::invalid_argument& e) 1088a3afd70SShawn McCarney { 1098a3afd70SShawn McCarney EXPECT_STREQ(e.what(), "Invalid chassis number: 0"); 1108a3afd70SShawn McCarney } 1118a3afd70SShawn McCarney catch (...) 1128a3afd70SShawn McCarney { 1138a3afd70SShawn McCarney ADD_FAILURE() << "Should not have caught exception."; 1148a3afd70SShawn McCarney } 1158a3afd70SShawn McCarney } 1168a3afd70SShawn McCarney 117*83058606SShawn McCarney TEST_F(ChassisTests, AddToIDMap) 118db0b833cSShawn McCarney { 119db0b833cSShawn McCarney // Create vector of Device objects 120db0b833cSShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 121db0b833cSShawn McCarney devices.emplace_back(createDevice("reg1", {"rail1"})); 122db0b833cSShawn McCarney devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"})); 123db0b833cSShawn McCarney devices.emplace_back(createDevice("reg3")); 124db0b833cSShawn McCarney 125db0b833cSShawn McCarney // Create Chassis 126cb3f6a63SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 127db0b833cSShawn McCarney 128db0b833cSShawn McCarney // Add Device and Rail objects within the Chassis to an IDMap 129db0b833cSShawn McCarney IDMap idMap{}; 130db0b833cSShawn McCarney chassis.addToIDMap(idMap); 131db0b833cSShawn McCarney 132db0b833cSShawn McCarney // Verify all Devices are in the IDMap 133db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getDevice("reg1")); 134db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getDevice("reg2")); 135db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getDevice("reg3")); 136db0b833cSShawn McCarney EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument); 137db0b833cSShawn McCarney 138db0b833cSShawn McCarney // Verify all Rails are in the IDMap 139db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getRail("rail1")); 140db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getRail("rail2a")); 141db0b833cSShawn McCarney EXPECT_NO_THROW(idMap.getRail("rail2b")); 142db0b833cSShawn McCarney EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument); 143db0b833cSShawn McCarney } 144db0b833cSShawn McCarney 145*83058606SShawn McCarney TEST_F(ChassisTests, ClearCache) 1469bd94d36SShawn McCarney { 1479bd94d36SShawn McCarney // Create PresenceDetection 1489bd94d36SShawn McCarney std::vector<std::unique_ptr<Action>> actions{}; 149*83058606SShawn McCarney auto presenceDetection = 1509bd94d36SShawn McCarney std::make_unique<PresenceDetection>(std::move(actions)); 1519bd94d36SShawn McCarney PresenceDetection* presenceDetectionPtr = presenceDetection.get(); 1529bd94d36SShawn McCarney 1539bd94d36SShawn McCarney // Create Device that contains PresenceDetection 154*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 155*83058606SShawn McCarney auto device = std::make_unique<Device>( 1569bd94d36SShawn McCarney "reg1", true, 1579bd94d36SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 1589bd94d36SShawn McCarney std::move(i2cInterface), std::move(presenceDetection)); 1599bd94d36SShawn McCarney Device* devicePtr = device.get(); 1609bd94d36SShawn McCarney 1619bd94d36SShawn McCarney // Create Chassis that contains Device 1629bd94d36SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 1639bd94d36SShawn McCarney devices.emplace_back(std::move(device)); 164*83058606SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 1659bd94d36SShawn McCarney 1669bd94d36SShawn McCarney // Cache presence value in PresenceDetection 1679bd94d36SShawn McCarney MockServices services{}; 168*83058606SShawn McCarney presenceDetectionPtr->execute(services, *system, chassis, *devicePtr); 1699bd94d36SShawn McCarney EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value()); 1709bd94d36SShawn McCarney 1719bd94d36SShawn McCarney // Clear cached data in Chassis 172*83058606SShawn McCarney chassis.clearCache(); 1739bd94d36SShawn McCarney 1749bd94d36SShawn McCarney // Verify presence value no longer cached in PresenceDetection 1759bd94d36SShawn McCarney EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value()); 1769bd94d36SShawn McCarney } 1779bd94d36SShawn McCarney 178*83058606SShawn McCarney TEST_F(ChassisTests, ClearErrorHistory) 1799f3e54e6SShawn McCarney { 1809f3e54e6SShawn McCarney // Create SensorMonitoring. Will fail with a DBus exception. 181*83058606SShawn McCarney auto action = std::make_unique<MockAction>(); 1829f3e54e6SShawn McCarney EXPECT_CALL(*action, execute) 1839f3e54e6SShawn McCarney .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"})); 1849f3e54e6SShawn McCarney std::vector<std::unique_ptr<Action>> actions{}; 1859f3e54e6SShawn McCarney actions.emplace_back(std::move(action)); 186*83058606SShawn McCarney auto sensorMonitoring = 1879f3e54e6SShawn McCarney std::make_unique<SensorMonitoring>(std::move(actions)); 1889f3e54e6SShawn McCarney 1899f3e54e6SShawn McCarney // Create Rail 1909f3e54e6SShawn McCarney std::unique_ptr<Configuration> configuration{}; 191*83058606SShawn McCarney auto rail = std::make_unique<Rail>("vddr1", std::move(configuration), 192*83058606SShawn McCarney std::move(sensorMonitoring)); 1939f3e54e6SShawn McCarney 1949f3e54e6SShawn McCarney // Create Device that contains Rail 195*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 1969f3e54e6SShawn McCarney std::unique_ptr<PresenceDetection> presenceDetection{}; 1979f3e54e6SShawn McCarney std::unique_ptr<Configuration> deviceConfiguration{}; 19832252599SShawn McCarney std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 1999f3e54e6SShawn McCarney std::vector<std::unique_ptr<Rail>> rails{}; 2009f3e54e6SShawn McCarney rails.emplace_back(std::move(rail)); 201*83058606SShawn McCarney auto device = std::make_unique<Device>( 2029f3e54e6SShawn McCarney "reg1", true, 2039f3e54e6SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 2049f3e54e6SShawn McCarney std::move(i2cInterface), std::move(presenceDetection), 20532252599SShawn McCarney std::move(deviceConfiguration), std::move(phaseFaultDetection), 20632252599SShawn McCarney std::move(rails)); 2079f3e54e6SShawn McCarney 2089f3e54e6SShawn McCarney // Create Chassis that contains Device 2099f3e54e6SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 2109f3e54e6SShawn McCarney devices.emplace_back(std::move(device)); 211*83058606SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 2129f3e54e6SShawn McCarney 2139f3e54e6SShawn McCarney // Create mock services 2149f3e54e6SShawn McCarney MockServices services{}; 2159f3e54e6SShawn McCarney 2169f3e54e6SShawn McCarney // Expect Sensors service to be called 5+5=10 times 2179f3e54e6SShawn McCarney MockSensors& sensors = services.getMockSensors(); 2189f3e54e6SShawn McCarney EXPECT_CALL(sensors, startRail).Times(10); 2199f3e54e6SShawn McCarney EXPECT_CALL(sensors, setValue).Times(0); 2209f3e54e6SShawn McCarney EXPECT_CALL(sensors, endRail).Times(10); 2219f3e54e6SShawn McCarney 2229f3e54e6SShawn McCarney // Expect Journal service to be called 3+3=6 times to log error messages 2239f3e54e6SShawn McCarney MockJournal& journal = services.getMockJournal(); 2249f3e54e6SShawn McCarney EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>())) 2259f3e54e6SShawn McCarney .Times(6); 2269f3e54e6SShawn McCarney EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6); 2279f3e54e6SShawn McCarney 2289f3e54e6SShawn McCarney // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error 2299f3e54e6SShawn McCarney MockErrorLogging& errorLogging = services.getMockErrorLogging(); 2309f3e54e6SShawn McCarney EXPECT_CALL(errorLogging, logDBusError).Times(2); 2319f3e54e6SShawn McCarney 2329f3e54e6SShawn McCarney // Monitor sensors 5 times. Should fail every time, write to journal 3 2339f3e54e6SShawn McCarney // times, and log one error. 2349f3e54e6SShawn McCarney for (int i = 1; i <= 5; ++i) 2359f3e54e6SShawn McCarney { 236*83058606SShawn McCarney chassis.monitorSensors(services, *system); 2379f3e54e6SShawn McCarney } 2389f3e54e6SShawn McCarney 2399f3e54e6SShawn McCarney // Clear error history 240*83058606SShawn McCarney chassis.clearErrorHistory(); 2419f3e54e6SShawn McCarney 2429f3e54e6SShawn McCarney // Monitor sensors 5 times again. Should fail every time, write to journal 2439f3e54e6SShawn McCarney // 3 times, and log one error. 2449f3e54e6SShawn McCarney for (int i = 1; i <= 5; ++i) 2459f3e54e6SShawn McCarney { 246*83058606SShawn McCarney chassis.monitorSensors(services, *system); 2479f3e54e6SShawn McCarney } 2489f3e54e6SShawn McCarney } 2499f3e54e6SShawn McCarney 250*83058606SShawn McCarney TEST_F(ChassisTests, CloseDevices) 251050531f5SShawn McCarney { 252050531f5SShawn McCarney // Test where no devices were specified in constructor 253050531f5SShawn McCarney { 254d692d6dfSBob King // Create mock services. Expect logDebug() to be called. 255d692d6dfSBob King MockServices services{}; 256d692d6dfSBob King MockJournal& journal = services.getMockJournal(); 257d692d6dfSBob King EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1); 258d692d6dfSBob King 259050531f5SShawn McCarney // Create Chassis 260cb3f6a63SShawn McCarney Chassis chassis{2, defaultInventoryPath}; 261050531f5SShawn McCarney 262050531f5SShawn McCarney // Call closeDevices() 263d692d6dfSBob King chassis.closeDevices(services); 264050531f5SShawn McCarney } 265050531f5SShawn McCarney 266050531f5SShawn McCarney // Test where devices were specified in constructor 267050531f5SShawn McCarney { 268050531f5SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 269050531f5SShawn McCarney 270d692d6dfSBob King // Create mock services. Expect logDebug() to be called. 271d692d6dfSBob King MockServices services{}; 272d692d6dfSBob King MockJournal& journal = services.getMockJournal(); 273d692d6dfSBob King EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1); 274d692d6dfSBob King 275050531f5SShawn McCarney // Create Device vdd0_reg 276050531f5SShawn McCarney { 277050531f5SShawn McCarney // Create mock I2CInterface: isOpen() and close() should be called 278*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 279050531f5SShawn McCarney EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 280050531f5SShawn McCarney EXPECT_CALL(*i2cInterface, close).Times(1); 281050531f5SShawn McCarney 282050531f5SShawn McCarney // Create Device 283*83058606SShawn McCarney auto device = 284a76898f1SBob King std::make_unique<Device>("vdd0_reg", true, 285a76898f1SBob King "/xyz/openbmc_project/inventory/" 286a76898f1SBob King "system/chassis/motherboard/vdd0_reg", 287050531f5SShawn McCarney std::move(i2cInterface)); 288050531f5SShawn McCarney devices.emplace_back(std::move(device)); 289050531f5SShawn McCarney } 290050531f5SShawn McCarney 291050531f5SShawn McCarney // Create Device vdd1_reg 292050531f5SShawn McCarney { 293050531f5SShawn McCarney // Create mock I2CInterface: isOpen() and close() should be called 294*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 295050531f5SShawn McCarney EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 296050531f5SShawn McCarney EXPECT_CALL(*i2cInterface, close).Times(1); 297050531f5SShawn McCarney 298050531f5SShawn McCarney // Create Device 299*83058606SShawn McCarney auto device = 300a76898f1SBob King std::make_unique<Device>("vdd1_reg", true, 301a76898f1SBob King "/xyz/openbmc_project/inventory/" 302a76898f1SBob King "system/chassis/motherboard/vdd1_reg", 303050531f5SShawn McCarney std::move(i2cInterface)); 304050531f5SShawn McCarney devices.emplace_back(std::move(device)); 305050531f5SShawn McCarney } 306050531f5SShawn McCarney 307050531f5SShawn McCarney // Create Chassis 308cb3f6a63SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 309050531f5SShawn McCarney 310050531f5SShawn McCarney // Call closeDevices() 311d692d6dfSBob King chassis.closeDevices(services); 312050531f5SShawn McCarney } 313050531f5SShawn McCarney } 314050531f5SShawn McCarney 315*83058606SShawn McCarney TEST_F(ChassisTests, Configure) 316525e20c9SShawn McCarney { 317525e20c9SShawn McCarney // Test where no devices were specified in constructor 318525e20c9SShawn McCarney { 3195cfe5103SBob King // Create mock services. Expect logInfo() to be called. 32023243f84SBob King MockServices services{}; 3215cfe5103SBob King MockJournal& journal = services.getMockJournal(); 3225cfe5103SBob King EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1); 3235cfe5103SBob King EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0); 3245cfe5103SBob King EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 32523243f84SBob King 326525e20c9SShawn McCarney // Create Chassis 327*83058606SShawn McCarney Chassis chassis{1, defaultInventoryPath}; 328525e20c9SShawn McCarney 329525e20c9SShawn McCarney // Call configure() 330*83058606SShawn McCarney chassis.configure(services, *system); 331525e20c9SShawn McCarney } 332525e20c9SShawn McCarney 333525e20c9SShawn McCarney // Test where devices were specified in constructor 334525e20c9SShawn McCarney { 335525e20c9SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 336525e20c9SShawn McCarney 3375cfe5103SBob King // Create mock services. Expect logInfo() and logDebug() to be called. 3385cfe5103SBob King MockServices services{}; 3395cfe5103SBob King MockJournal& journal = services.getMockJournal(); 3405cfe5103SBob King EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1); 3415cfe5103SBob King EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000")) 3425cfe5103SBob King .Times(1); 3435cfe5103SBob King EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000")) 3445cfe5103SBob King .Times(1); 3455cfe5103SBob King EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 3465cfe5103SBob King 347525e20c9SShawn McCarney // Create Device vdd0_reg 348525e20c9SShawn McCarney { 349525e20c9SShawn McCarney // Create Configuration 350525e20c9SShawn McCarney std::vector<std::unique_ptr<Action>> actions{}; 351*83058606SShawn McCarney auto configuration = 352525e20c9SShawn McCarney std::make_unique<Configuration>(1.3, std::move(actions)); 353525e20c9SShawn McCarney 354525e20c9SShawn McCarney // Create Device 355*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 356525e20c9SShawn McCarney std::unique_ptr<PresenceDetection> presenceDetection{}; 357*83058606SShawn McCarney auto device = std::make_unique<Device>( 358a76898f1SBob King "vdd0_reg", true, 359a76898f1SBob King "/xyz/openbmc_project/inventory/system/chassis/motherboard/" 360a76898f1SBob King "vdd0_reg", 361525e20c9SShawn McCarney std::move(i2cInterface), std::move(presenceDetection), 362525e20c9SShawn McCarney std::move(configuration)); 363525e20c9SShawn McCarney devices.emplace_back(std::move(device)); 364525e20c9SShawn McCarney } 365525e20c9SShawn McCarney 366525e20c9SShawn McCarney // Create Device vdd1_reg 367525e20c9SShawn McCarney { 368525e20c9SShawn McCarney // Create Configuration 369525e20c9SShawn McCarney std::vector<std::unique_ptr<Action>> actions{}; 370*83058606SShawn McCarney auto configuration = 371525e20c9SShawn McCarney std::make_unique<Configuration>(1.2, std::move(actions)); 372525e20c9SShawn McCarney 373525e20c9SShawn McCarney // Create Device 374*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 375525e20c9SShawn McCarney std::unique_ptr<PresenceDetection> presenceDetection{}; 376*83058606SShawn McCarney auto device = std::make_unique<Device>( 377a76898f1SBob King "vdd1_reg", true, 378a76898f1SBob King "/xyz/openbmc_project/inventory/system/chassis/motherboard/" 379a76898f1SBob King "vdd1_reg", 380525e20c9SShawn McCarney std::move(i2cInterface), std::move(presenceDetection), 381525e20c9SShawn McCarney std::move(configuration)); 382525e20c9SShawn McCarney devices.emplace_back(std::move(device)); 383525e20c9SShawn McCarney } 384525e20c9SShawn McCarney 385525e20c9SShawn McCarney // Create Chassis 386*83058606SShawn McCarney Chassis chassis{2, defaultInventoryPath, std::move(devices)}; 387525e20c9SShawn McCarney 388525e20c9SShawn McCarney // Call configure() 389*83058606SShawn McCarney chassis.configure(services, *system); 390525e20c9SShawn McCarney } 391525e20c9SShawn McCarney } 392525e20c9SShawn McCarney 393*83058606SShawn McCarney TEST_F(ChassisTests, GetDevices) 3948a3afd70SShawn McCarney { 3958a3afd70SShawn McCarney // Test where no devices were specified in constructor 3968a3afd70SShawn McCarney { 397cb3f6a63SShawn McCarney Chassis chassis{2, defaultInventoryPath}; 3988a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices().size(), 0); 3998a3afd70SShawn McCarney } 4008a3afd70SShawn McCarney 4018a3afd70SShawn McCarney // Test where devices were specified in constructor 4028a3afd70SShawn McCarney { 4038a3afd70SShawn McCarney // Create vector of Device objects 4048a3afd70SShawn McCarney std::vector<std::unique_ptr<Device>> devices{}; 405db0b833cSShawn McCarney devices.emplace_back(createDevice("vdd_reg1")); 406db0b833cSShawn McCarney devices.emplace_back(createDevice("vdd_reg2")); 4078a3afd70SShawn McCarney 4088a3afd70SShawn McCarney // Create Chassis 409cb3f6a63SShawn McCarney Chassis chassis{1, defaultInventoryPath, std::move(devices)}; 4108a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices().size(), 2); 4118a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1"); 4128a3afd70SShawn McCarney EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2"); 4138a3afd70SShawn McCarney } 4148a3afd70SShawn McCarney } 4158a3afd70SShawn McCarney 416*83058606SShawn McCarney TEST_F(ChassisTests, GetInventoryPath) 417cb3f6a63SShawn McCarney { 418cb3f6a63SShawn McCarney Chassis chassis{3, defaultInventoryPath}; 419cb3f6a63SShawn McCarney EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath); 420cb3f6a63SShawn McCarney } 421cb3f6a63SShawn McCarney 422*83058606SShawn McCarney TEST_F(ChassisTests, GetNumber) 4238a3afd70SShawn McCarney { 424cb3f6a63SShawn McCarney Chassis chassis{3, defaultInventoryPath}; 4258a3afd70SShawn McCarney EXPECT_EQ(chassis.getNumber(), 3); 4268a3afd70SShawn McCarney } 427a2c81a61SBob King 428*83058606SShawn McCarney TEST_F(ChassisTests, MonitorSensors) 429a2c81a61SBob King { 430a2c81a61SBob King // Test where no devices were specified in constructor 431a2c81a61SBob King { 43217bac89eSShawn McCarney // Create mock services. No Sensors methods should be called. 4338a55292dSBob King MockServices services{}; 43417bac89eSShawn McCarney MockSensors& sensors = services.getMockSensors(); 43517bac89eSShawn McCarney EXPECT_CALL(sensors, startRail).Times(0); 43617bac89eSShawn McCarney EXPECT_CALL(sensors, setValue).Times(0); 43717bac89eSShawn McCarney EXPECT_CALL(sensors, endRail).Times(0); 4388a55292dSBob King 439a2c81a61SBob King // Create Chassis 440*83058606SShawn McCarney Chassis chassis{1, defaultInventoryPath}; 441a2c81a61SBob King 442a2c81a61SBob King // Call monitorSensors(). Should do nothing. 443*83058606SShawn McCarney chassis.monitorSensors(services, *system); 444a2c81a61SBob King } 445a2c81a61SBob King 446a2c81a61SBob King // Test where devices were specified in constructor 447a2c81a61SBob King { 44817bac89eSShawn McCarney // Create mock services. Set Sensors service expectations. 4498a55292dSBob King MockServices services{}; 45017bac89eSShawn McCarney MockSensors& sensors = services.getMockSensors(); 45117bac89eSShawn McCarney EXPECT_CALL(sensors, startRail("vdd0", 45217bac89eSShawn McCarney "/xyz/openbmc_project/inventory/system/" 45317bac89eSShawn McCarney "chassis/motherboard/vdd0_reg", 45417bac89eSShawn McCarney defaultInventoryPath)) 45517bac89eSShawn McCarney .Times(1); 45617bac89eSShawn McCarney EXPECT_CALL(sensors, startRail("vdd1", 45717bac89eSShawn McCarney "/xyz/openbmc_project/inventory/system/" 45817bac89eSShawn McCarney "chassis/motherboard/vdd1_reg", 45917bac89eSShawn McCarney defaultInventoryPath)) 46017bac89eSShawn McCarney .Times(1); 46117bac89eSShawn McCarney EXPECT_CALL(sensors, setValue).Times(0); 46217bac89eSShawn McCarney EXPECT_CALL(sensors, endRail(false)).Times(2); 4638a55292dSBob King 464a2c81a61SBob King std::vector<std::unique_ptr<Device>> devices{}; 465a2c81a61SBob King 46617bac89eSShawn McCarney // Create Device vdd0_reg 46717bac89eSShawn McCarney { 46817bac89eSShawn McCarney // Create SensorMonitoring for Rail 469*83058606SShawn McCarney auto action = std::make_unique<MockAction>(); 47017bac89eSShawn McCarney EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 471a2c81a61SBob King std::vector<std::unique_ptr<Action>> actions{}; 472a2c81a61SBob King actions.emplace_back(std::move(action)); 473*83058606SShawn McCarney auto sensorMonitoring = 474a2c81a61SBob King std::make_unique<SensorMonitoring>(std::move(actions)); 475a2c81a61SBob King 476a2c81a61SBob King // Create Rail 477a2c81a61SBob King std::unique_ptr<Configuration> configuration{}; 478*83058606SShawn McCarney auto rail = std::make_unique<Rail>("vdd0", std::move(configuration), 479*83058606SShawn McCarney std::move(sensorMonitoring)); 480a2c81a61SBob King 481a2c81a61SBob King // Create Device 482*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 483a2c81a61SBob King std::unique_ptr<PresenceDetection> presenceDetection{}; 484a2c81a61SBob King std::unique_ptr<Configuration> deviceConfiguration{}; 48532252599SShawn McCarney std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 48617bac89eSShawn McCarney std::vector<std::unique_ptr<Rail>> rails{}; 48717bac89eSShawn McCarney rails.emplace_back(std::move(rail)); 488*83058606SShawn McCarney auto device = std::make_unique<Device>( 48917bac89eSShawn McCarney "vdd0_reg", true, 49017bac89eSShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/" 49117bac89eSShawn McCarney "vdd0_reg", 492a2c81a61SBob King std::move(i2cInterface), std::move(presenceDetection), 49332252599SShawn McCarney std::move(deviceConfiguration), std::move(phaseFaultDetection), 49432252599SShawn McCarney std::move(rails)); 495a2c81a61SBob King devices.emplace_back(std::move(device)); 49617bac89eSShawn McCarney } 49717bac89eSShawn McCarney 49817bac89eSShawn McCarney // Create Device vdd1_reg 49917bac89eSShawn McCarney { 50017bac89eSShawn McCarney // Create SensorMonitoring for Rail 501*83058606SShawn McCarney auto action = std::make_unique<MockAction>(); 50217bac89eSShawn McCarney EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 50317bac89eSShawn McCarney std::vector<std::unique_ptr<Action>> actions{}; 50417bac89eSShawn McCarney actions.emplace_back(std::move(action)); 505*83058606SShawn McCarney auto sensorMonitoring = 50617bac89eSShawn McCarney std::make_unique<SensorMonitoring>(std::move(actions)); 50717bac89eSShawn McCarney 50817bac89eSShawn McCarney // Create Rail 50917bac89eSShawn McCarney std::unique_ptr<Configuration> configuration{}; 510*83058606SShawn McCarney auto rail = std::make_unique<Rail>("vdd1", std::move(configuration), 511*83058606SShawn McCarney std::move(sensorMonitoring)); 51217bac89eSShawn McCarney 51317bac89eSShawn McCarney // Create Device 514*83058606SShawn McCarney auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 51517bac89eSShawn McCarney std::unique_ptr<PresenceDetection> presenceDetection{}; 51617bac89eSShawn McCarney std::unique_ptr<Configuration> deviceConfiguration{}; 51732252599SShawn McCarney std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 51817bac89eSShawn McCarney std::vector<std::unique_ptr<Rail>> rails{}; 51917bac89eSShawn McCarney rails.emplace_back(std::move(rail)); 520*83058606SShawn McCarney auto device = std::make_unique<Device>( 52117bac89eSShawn McCarney "vdd1_reg", true, 52217bac89eSShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/" 52317bac89eSShawn McCarney "vdd1_reg", 52417bac89eSShawn McCarney std::move(i2cInterface), std::move(presenceDetection), 52532252599SShawn McCarney std::move(deviceConfiguration), std::move(phaseFaultDetection), 52632252599SShawn McCarney std::move(rails)); 52717bac89eSShawn McCarney devices.emplace_back(std::move(device)); 52817bac89eSShawn McCarney } 52917bac89eSShawn McCarney 53017bac89eSShawn McCarney // Create Chassis that contains Devices 531*83058606SShawn McCarney Chassis chassis{2, defaultInventoryPath, std::move(devices)}; 532a2c81a61SBob King 533a2c81a61SBob King // Call monitorSensors() 534*83058606SShawn McCarney chassis.monitorSensors(services, *system); 535a2c81a61SBob King } 536a2c81a61SBob King } 537