1 /** 2 * Copyright © 2020 IBM Corporation 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 #include "action.hpp" 17 #include "chassis.hpp" 18 #include "configuration.hpp" 19 #include "device.hpp" 20 #include "i2c_interface.hpp" 21 #include "id_map.hpp" 22 #include "journal.hpp" 23 #include "mock_journal.hpp" 24 #include "presence_detection.hpp" 25 #include "rail.hpp" 26 #include "rule.hpp" 27 #include "system.hpp" 28 #include "test_utils.hpp" 29 30 #include <memory> 31 #include <stdexcept> 32 #include <string> 33 #include <utility> 34 #include <vector> 35 36 #include <gtest/gtest.h> 37 38 using namespace phosphor::power::regulators; 39 using namespace phosphor::power::regulators::test_utils; 40 41 TEST(ChassisTests, Constructor) 42 { 43 // Test where works: Only required parameters are specified 44 { 45 Chassis chassis{2}; 46 EXPECT_EQ(chassis.getNumber(), 2); 47 EXPECT_EQ(chassis.getDevices().size(), 0); 48 } 49 50 // Test where works: All parameters are specified 51 { 52 // Create vector of Device objects 53 std::vector<std::unique_ptr<Device>> devices{}; 54 devices.emplace_back(createDevice("vdd_reg1")); 55 devices.emplace_back(createDevice("vdd_reg2")); 56 57 // Create Chassis 58 Chassis chassis{1, std::move(devices)}; 59 EXPECT_EQ(chassis.getNumber(), 1); 60 EXPECT_EQ(chassis.getDevices().size(), 2); 61 } 62 63 // Test where fails: Invalid chassis number < 1 64 try 65 { 66 Chassis chassis{0}; 67 ADD_FAILURE() << "Should not have reached this line."; 68 } 69 catch (const std::invalid_argument& e) 70 { 71 EXPECT_STREQ(e.what(), "Invalid chassis number: 0"); 72 } 73 catch (...) 74 { 75 ADD_FAILURE() << "Should not have caught exception."; 76 } 77 } 78 79 TEST(ChassisTests, AddToIDMap) 80 { 81 // Create vector of Device objects 82 std::vector<std::unique_ptr<Device>> devices{}; 83 devices.emplace_back(createDevice("reg1", {"rail1"})); 84 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"})); 85 devices.emplace_back(createDevice("reg3")); 86 87 // Create Chassis 88 Chassis chassis{1, std::move(devices)}; 89 90 // Add Device and Rail objects within the Chassis to an IDMap 91 IDMap idMap{}; 92 chassis.addToIDMap(idMap); 93 94 // Verify all Devices are in the IDMap 95 EXPECT_NO_THROW(idMap.getDevice("reg1")); 96 EXPECT_NO_THROW(idMap.getDevice("reg2")); 97 EXPECT_NO_THROW(idMap.getDevice("reg3")); 98 EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument); 99 100 // Verify all Rails are in the IDMap 101 EXPECT_NO_THROW(idMap.getRail("rail1")); 102 EXPECT_NO_THROW(idMap.getRail("rail2a")); 103 EXPECT_NO_THROW(idMap.getRail("rail2b")); 104 EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument); 105 } 106 107 TEST(ChassisTests, Configure) 108 { 109 // Test where no devices were specified in constructor 110 { 111 // Create Chassis 112 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(1); 113 Chassis* chassisPtr = chassis.get(); 114 115 // Create System that contains Chassis 116 std::vector<std::unique_ptr<Rule>> rules{}; 117 std::vector<std::unique_ptr<Chassis>> chassisVec{}; 118 chassisVec.emplace_back(std::move(chassis)); 119 System system{std::move(rules), std::move(chassisVec)}; 120 121 // Call configure() 122 journal::clear(); 123 chassisPtr->configure(system); 124 EXPECT_EQ(journal::getDebugMessages().size(), 0); 125 EXPECT_EQ(journal::getErrMessages().size(), 0); 126 std::vector<std::string> expectedInfoMessages{"Configuring chassis 1"}; 127 EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages); 128 } 129 130 // Test where devices were specified in constructor 131 { 132 std::vector<std::unique_ptr<Device>> devices{}; 133 134 // Create Device vdd0_reg 135 { 136 // Create Configuration 137 std::vector<std::unique_ptr<Action>> actions{}; 138 std::unique_ptr<Configuration> configuration = 139 std::make_unique<Configuration>(1.3, std::move(actions)); 140 141 // Create Device 142 std::unique_ptr<i2c::I2CInterface> i2cInterface = 143 createI2CInterface(); 144 std::unique_ptr<PresenceDetection> presenceDetection{}; 145 std::unique_ptr<Device> device = std::make_unique<Device>( 146 "vdd0_reg", true, "/system/chassis/motherboard/vdd0_reg", 147 std::move(i2cInterface), std::move(presenceDetection), 148 std::move(configuration)); 149 devices.emplace_back(std::move(device)); 150 } 151 152 // Create Device vdd1_reg 153 { 154 // Create Configuration 155 std::vector<std::unique_ptr<Action>> actions{}; 156 std::unique_ptr<Configuration> configuration = 157 std::make_unique<Configuration>(1.2, std::move(actions)); 158 159 // Create Device 160 std::unique_ptr<i2c::I2CInterface> i2cInterface = 161 createI2CInterface(); 162 std::unique_ptr<PresenceDetection> presenceDetection{}; 163 std::unique_ptr<Device> device = std::make_unique<Device>( 164 "vdd1_reg", true, "/system/chassis/motherboard/vdd1_reg", 165 std::move(i2cInterface), std::move(presenceDetection), 166 std::move(configuration)); 167 devices.emplace_back(std::move(device)); 168 } 169 170 // Create Chassis 171 std::unique_ptr<Chassis> chassis = 172 std::make_unique<Chassis>(2, std::move(devices)); 173 Chassis* chassisPtr = chassis.get(); 174 175 // Create System that contains Chassis 176 std::vector<std::unique_ptr<Rule>> rules{}; 177 std::vector<std::unique_ptr<Chassis>> chassisVec{}; 178 chassisVec.emplace_back(std::move(chassis)); 179 System system{std::move(rules), std::move(chassisVec)}; 180 181 // Call configure() 182 journal::clear(); 183 chassisPtr->configure(system); 184 std::vector<std::string> expectedDebugMessages{ 185 "Configuring vdd0_reg: volts=1.300000", 186 "Configuring vdd1_reg: volts=1.200000"}; 187 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages); 188 EXPECT_EQ(journal::getErrMessages().size(), 0); 189 std::vector<std::string> expectedInfoMessages{"Configuring chassis 2"}; 190 EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages); 191 } 192 } 193 194 TEST(ChassisTests, GetDevices) 195 { 196 // Test where no devices were specified in constructor 197 { 198 Chassis chassis{2}; 199 EXPECT_EQ(chassis.getDevices().size(), 0); 200 } 201 202 // Test where devices were specified in constructor 203 { 204 // Create vector of Device objects 205 std::vector<std::unique_ptr<Device>> devices{}; 206 devices.emplace_back(createDevice("vdd_reg1")); 207 devices.emplace_back(createDevice("vdd_reg2")); 208 209 // Create Chassis 210 Chassis chassis{1, std::move(devices)}; 211 EXPECT_EQ(chassis.getDevices().size(), 2); 212 EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1"); 213 EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2"); 214 } 215 } 216 217 TEST(ChassisTests, GetNumber) 218 { 219 Chassis chassis{3}; 220 EXPECT_EQ(chassis.getNumber(), 3); 221 } 222