blob: 5f8266e893214f91c37a6309b69946534c4fd4cf [file] [log] [blame]
Shawn McCarney8a3afd72020-03-12 14:28:44 -05001/**
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 */
Shawn McCarney525e20c2020-04-14 11:05:39 -050016#include "action.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050017#include "chassis.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050018#include "configuration.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050019#include "device.hpp"
20#include "i2c_interface.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050021#include "id_map.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050022#include "journal.hpp"
23#include "mock_journal.hpp"
Shawn McCarney050531f2020-06-02 14:17:12 -050024#include "mocked_i2c_interface.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050025#include "presence_detection.hpp"
26#include "rail.hpp"
27#include "rule.hpp"
28#include "system.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050029#include "test_utils.hpp"
30
31#include <memory>
32#include <stdexcept>
Shawn McCarney525e20c2020-04-14 11:05:39 -050033#include <string>
Shawn McCarney8a3afd72020-03-12 14:28:44 -050034#include <utility>
35#include <vector>
36
37#include <gtest/gtest.h>
38
39using namespace phosphor::power::regulators;
40using namespace phosphor::power::regulators::test_utils;
41
Shawn McCarney050531f2020-06-02 14:17:12 -050042using ::testing::Return;
43
Shawn McCarney8a3afd72020-03-12 14:28:44 -050044TEST(ChassisTests, Constructor)
45{
46 // Test where works: Only required parameters are specified
47 {
48 Chassis chassis{2};
49 EXPECT_EQ(chassis.getNumber(), 2);
50 EXPECT_EQ(chassis.getDevices().size(), 0);
51 }
52
53 // Test where works: All parameters are specified
54 {
55 // Create vector of Device objects
56 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050057 devices.emplace_back(createDevice("vdd_reg1"));
58 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -050059
60 // Create Chassis
61 Chassis chassis{1, std::move(devices)};
62 EXPECT_EQ(chassis.getNumber(), 1);
63 EXPECT_EQ(chassis.getDevices().size(), 2);
64 }
65
66 // Test where fails: Invalid chassis number < 1
67 try
68 {
69 Chassis chassis{0};
70 ADD_FAILURE() << "Should not have reached this line.";
71 }
72 catch (const std::invalid_argument& e)
73 {
74 EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
75 }
76 catch (...)
77 {
78 ADD_FAILURE() << "Should not have caught exception.";
79 }
80}
81
Shawn McCarneydb0b8332020-04-06 14:13:04 -050082TEST(ChassisTests, AddToIDMap)
83{
84 // Create vector of Device objects
85 std::vector<std::unique_ptr<Device>> devices{};
86 devices.emplace_back(createDevice("reg1", {"rail1"}));
87 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
88 devices.emplace_back(createDevice("reg3"));
89
90 // Create Chassis
91 Chassis chassis{1, std::move(devices)};
92
93 // Add Device and Rail objects within the Chassis to an IDMap
94 IDMap idMap{};
95 chassis.addToIDMap(idMap);
96
97 // Verify all Devices are in the IDMap
98 EXPECT_NO_THROW(idMap.getDevice("reg1"));
99 EXPECT_NO_THROW(idMap.getDevice("reg2"));
100 EXPECT_NO_THROW(idMap.getDevice("reg3"));
101 EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
102
103 // Verify all Rails are in the IDMap
104 EXPECT_NO_THROW(idMap.getRail("rail1"));
105 EXPECT_NO_THROW(idMap.getRail("rail2a"));
106 EXPECT_NO_THROW(idMap.getRail("rail2b"));
107 EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
108}
109
Shawn McCarney050531f2020-06-02 14:17:12 -0500110TEST(ChassisTests, CloseDevices)
111{
112 // Test where no devices were specified in constructor
113 {
114 // Create Chassis
115 Chassis chassis{2};
116
117 // Call closeDevices()
118 journal::clear();
119 chassis.closeDevices();
120 EXPECT_EQ(journal::getErrMessages().size(), 0);
121 EXPECT_EQ(journal::getInfoMessages().size(), 0);
122 std::vector<std::string> expectedDebugMessages{
123 "Closing devices in chassis 2"};
124 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
125 }
126
127 // Test where devices were specified in constructor
128 {
129 std::vector<std::unique_ptr<Device>> devices{};
130
131 // Create Device vdd0_reg
132 {
133 // Create mock I2CInterface: isOpen() and close() should be called
134 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
135 std::make_unique<i2c::MockedI2CInterface>();
136 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
137 EXPECT_CALL(*i2cInterface, close).Times(1);
138
139 // Create Device
140 std::unique_ptr<Device> device = std::make_unique<Device>(
141 "vdd0_reg", true, "/system/chassis/motherboard/vdd0_reg",
142 std::move(i2cInterface));
143 devices.emplace_back(std::move(device));
144 }
145
146 // Create Device vdd1_reg
147 {
148 // Create mock I2CInterface: isOpen() and close() should be called
149 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
150 std::make_unique<i2c::MockedI2CInterface>();
151 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
152 EXPECT_CALL(*i2cInterface, close).Times(1);
153
154 // Create Device
155 std::unique_ptr<Device> device = std::make_unique<Device>(
156 "vdd1_reg", true, "/system/chassis/motherboard/vdd1_reg",
157 std::move(i2cInterface));
158 devices.emplace_back(std::move(device));
159 }
160
161 // Create Chassis
162 Chassis chassis{1, std::move(devices)};
163
164 // Call closeDevices()
165 journal::clear();
166 chassis.closeDevices();
167 EXPECT_EQ(journal::getErrMessages().size(), 0);
168 EXPECT_EQ(journal::getInfoMessages().size(), 0);
169 std::vector<std::string> expectedDebugMessages{
170 "Closing devices in chassis 1"};
171 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
172 }
173}
174
Shawn McCarney525e20c2020-04-14 11:05:39 -0500175TEST(ChassisTests, Configure)
176{
177 // Test where no devices were specified in constructor
178 {
179 // Create Chassis
180 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(1);
181 Chassis* chassisPtr = chassis.get();
182
183 // Create System that contains Chassis
184 std::vector<std::unique_ptr<Rule>> rules{};
185 std::vector<std::unique_ptr<Chassis>> chassisVec{};
186 chassisVec.emplace_back(std::move(chassis));
187 System system{std::move(rules), std::move(chassisVec)};
188
189 // Call configure()
190 journal::clear();
191 chassisPtr->configure(system);
192 EXPECT_EQ(journal::getDebugMessages().size(), 0);
193 EXPECT_EQ(journal::getErrMessages().size(), 0);
194 std::vector<std::string> expectedInfoMessages{"Configuring chassis 1"};
195 EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages);
196 }
197
198 // Test where devices were specified in constructor
199 {
200 std::vector<std::unique_ptr<Device>> devices{};
201
202 // Create Device vdd0_reg
203 {
204 // Create Configuration
205 std::vector<std::unique_ptr<Action>> actions{};
206 std::unique_ptr<Configuration> configuration =
207 std::make_unique<Configuration>(1.3, std::move(actions));
208
209 // Create Device
210 std::unique_ptr<i2c::I2CInterface> i2cInterface =
211 createI2CInterface();
212 std::unique_ptr<PresenceDetection> presenceDetection{};
213 std::unique_ptr<Device> device = std::make_unique<Device>(
214 "vdd0_reg", true, "/system/chassis/motherboard/vdd0_reg",
215 std::move(i2cInterface), std::move(presenceDetection),
216 std::move(configuration));
217 devices.emplace_back(std::move(device));
218 }
219
220 // Create Device vdd1_reg
221 {
222 // Create Configuration
223 std::vector<std::unique_ptr<Action>> actions{};
224 std::unique_ptr<Configuration> configuration =
225 std::make_unique<Configuration>(1.2, std::move(actions));
226
227 // Create Device
228 std::unique_ptr<i2c::I2CInterface> i2cInterface =
229 createI2CInterface();
230 std::unique_ptr<PresenceDetection> presenceDetection{};
231 std::unique_ptr<Device> device = std::make_unique<Device>(
232 "vdd1_reg", true, "/system/chassis/motherboard/vdd1_reg",
233 std::move(i2cInterface), std::move(presenceDetection),
234 std::move(configuration));
235 devices.emplace_back(std::move(device));
236 }
237
238 // Create Chassis
239 std::unique_ptr<Chassis> chassis =
240 std::make_unique<Chassis>(2, std::move(devices));
241 Chassis* chassisPtr = chassis.get();
242
243 // Create System that contains Chassis
244 std::vector<std::unique_ptr<Rule>> rules{};
245 std::vector<std::unique_ptr<Chassis>> chassisVec{};
246 chassisVec.emplace_back(std::move(chassis));
247 System system{std::move(rules), std::move(chassisVec)};
248
249 // Call configure()
250 journal::clear();
251 chassisPtr->configure(system);
252 std::vector<std::string> expectedDebugMessages{
253 "Configuring vdd0_reg: volts=1.300000",
254 "Configuring vdd1_reg: volts=1.200000"};
255 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
256 EXPECT_EQ(journal::getErrMessages().size(), 0);
257 std::vector<std::string> expectedInfoMessages{"Configuring chassis 2"};
258 EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages);
259 }
260}
261
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500262TEST(ChassisTests, GetDevices)
263{
264 // Test where no devices were specified in constructor
265 {
266 Chassis chassis{2};
267 EXPECT_EQ(chassis.getDevices().size(), 0);
268 }
269
270 // Test where devices were specified in constructor
271 {
272 // Create vector of Device objects
273 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500274 devices.emplace_back(createDevice("vdd_reg1"));
275 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500276
277 // Create Chassis
278 Chassis chassis{1, std::move(devices)};
279 EXPECT_EQ(chassis.getDevices().size(), 2);
280 EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
281 EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
282 }
283}
284
285TEST(ChassisTests, GetNumber)
286{
287 Chassis chassis{3};
288 EXPECT_EQ(chassis.getNumber(), 3);
289}