blob: 901f1cfc6699fe6d1a14975c8c1b4ac461e3bc99 [file] [log] [blame]
Shawn McCarneya2461b32019-10-24 18:53:01 -05001/**
2 * Copyright © 2019 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 McCarney0b1a0e72020-03-11 18:01:44 -050016#include "action.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050017#include "chassis.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050018#include "configuration.hpp"
Shawn McCarneya2461b32019-10-24 18:53:01 -050019#include "device.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060020#include "i2c_interface.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050021#include "id_map.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050022#include "journal.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050023#include "mock_action.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050024#include "mock_journal.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050025#include "presence_detection.hpp"
26#include "rail.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050027#include "rule.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050028#include "system.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050029#include "test_utils.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060030
31#include <memory>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050032#include <optional>
Shawn McCarney525e20c2020-04-14 11:05:39 -050033#include <string>
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060034#include <utility>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050035#include <vector>
Shawn McCarneya2461b32019-10-24 18:53:01 -050036
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050037#include <gmock/gmock.h>
Shawn McCarneya2461b32019-10-24 18:53:01 -050038#include <gtest/gtest.h>
39
40using namespace phosphor::power::regulators;
Shawn McCarney8a3afd72020-03-12 14:28:44 -050041using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060042
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050043using ::testing::Return;
44
Shawn McCarneya2461b32019-10-24 18:53:01 -050045TEST(DeviceTests, Constructor)
46{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050047 // Test where only required parameters are specified
48 {
49 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
50 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
51 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
52 std::move(i2cInterface)};
53 EXPECT_EQ(device.getID(), "vdd_reg");
54 EXPECT_EQ(device.isRegulator(), true);
55 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg2");
56 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
57 EXPECT_EQ(device.getPresenceDetection(), nullptr);
58 EXPECT_EQ(device.getConfiguration(), nullptr);
59 EXPECT_EQ(device.getRails().size(), 0);
60 }
61
62 // Test where all parameters are specified
63 {
64 // Create I2CInterface
65 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
66 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
67
68 // Create PresenceDetection
69 std::vector<std::unique_ptr<Action>> actions{};
70 actions.push_back(std::make_unique<MockAction>());
71 std::unique_ptr<PresenceDetection> presenceDetection =
72 std::make_unique<PresenceDetection>(std::move(actions));
73
74 // Create Configuration
75 std::optional<double> volts{};
76 actions.clear();
77 actions.push_back(std::make_unique<MockAction>());
78 actions.push_back(std::make_unique<MockAction>());
79 std::unique_ptr<Configuration> configuration =
80 std::make_unique<Configuration>(volts, std::move(actions));
81
82 // Create vector of Rail objects
83 std::vector<std::unique_ptr<Rail>> rails{};
84 rails.push_back(std::make_unique<Rail>("vdd0"));
85 rails.push_back(std::make_unique<Rail>("vdd1"));
86
87 // Create Device
88 Device device{"vdd_reg",
89 false,
90 "/system/chassis/motherboard/reg1",
91 std::move(i2cInterface),
92 std::move(presenceDetection),
93 std::move(configuration),
94 std::move(rails)};
95 EXPECT_EQ(device.getID(), "vdd_reg");
96 EXPECT_EQ(device.isRegulator(), false);
97 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg1");
98 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
99 EXPECT_NE(device.getPresenceDetection(), nullptr);
100 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
101 EXPECT_NE(device.getConfiguration(), nullptr);
102 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), false);
103 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
104 EXPECT_EQ(device.getRails().size(), 2);
105 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500106}
107
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500108TEST(DeviceTests, AddToIDMap)
109{
110 std::unique_ptr<PresenceDetection> presenceDetection{};
111 std::unique_ptr<Configuration> configuration{};
112
113 // Create vector of Rail objects
114 std::vector<std::unique_ptr<Rail>> rails{};
115 rails.push_back(std::make_unique<Rail>("vdd0"));
116 rails.push_back(std::make_unique<Rail>("vdd1"));
117
118 // Create Device
119 Device device{"vdd_reg",
120 false,
121 "/system/chassis/motherboard/reg2",
122 std::move(createI2CInterface()),
123 std::move(presenceDetection),
124 std::move(configuration),
125 std::move(rails)};
126
127 // Add Device and Rail objects to an IDMap
128 IDMap idMap{};
129 device.addToIDMap(idMap);
130
131 // Verify Device is in the IDMap
132 EXPECT_NO_THROW(idMap.getDevice("vdd_reg"));
133 EXPECT_THROW(idMap.getDevice("vio_reg"), std::invalid_argument);
134
135 // Verify all Rails are in the IDMap
136 EXPECT_NO_THROW(idMap.getRail("vdd0"));
137 EXPECT_NO_THROW(idMap.getRail("vdd1"));
138 EXPECT_THROW(idMap.getRail("vdd2"), std::invalid_argument);
139}
140
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500141TEST(DeviceTests, Configure)
142{
143 // Test where Configuration and Rails were not specified in constructor
144 {
145 // Create Device
146 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
147 std::unique_ptr<Device> device = std::make_unique<Device>(
148 "reg1", true, "/system/chassis/motherboard/reg1",
149 std::move(i2cInterface));
150 Device* devicePtr = device.get();
151
152 // Create Chassis that contains Device
153 std::vector<std::unique_ptr<Device>> devices{};
154 devices.emplace_back(std::move(device));
155 std::unique_ptr<Chassis> chassis =
156 std::make_unique<Chassis>(1, std::move(devices));
157 Chassis* chassisPtr = chassis.get();
158
159 // Create System that contains Chassis
160 std::vector<std::unique_ptr<Rule>> rules{};
161 std::vector<std::unique_ptr<Chassis>> chassisVec{};
162 chassisVec.emplace_back(std::move(chassis));
163 System system{std::move(rules), std::move(chassisVec)};
164
165 // Call configure(). Should do nothing.
166 journal::clear();
167 devicePtr->configure(system, *chassisPtr);
168 EXPECT_EQ(journal::getDebugMessages().size(), 0);
169 EXPECT_EQ(journal::getErrMessages().size(), 0);
170 }
171
172 // Test where Configuration and Rails were specified in constructor
173 {
174 std::vector<std::unique_ptr<Rail>> rails{};
175
176 // Create Rail vdd0
177 {
178 // Create Configuration for Rail
179 std::optional<double> volts{1.3};
180 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
181 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
182 std::vector<std::unique_ptr<Action>> actions{};
183 actions.emplace_back(std::move(action));
184 std::unique_ptr<Configuration> configuration =
185 std::make_unique<Configuration>(volts, std::move(actions));
186
187 // Create Rail
188 std::unique_ptr<Rail> rail =
189 std::make_unique<Rail>("vdd0", std::move(configuration));
190 rails.emplace_back(std::move(rail));
191 }
192
193 // Create Rail vio0
194 {
195 // Create Configuration for Rail
196 std::optional<double> volts{3.2};
197 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
198 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
199 std::vector<std::unique_ptr<Action>> actions{};
200 actions.emplace_back(std::move(action));
201 std::unique_ptr<Configuration> configuration =
202 std::make_unique<Configuration>(volts, std::move(actions));
203
204 // Create Rail
205 std::unique_ptr<Rail> rail =
206 std::make_unique<Rail>("vio0", std::move(configuration));
207 rails.emplace_back(std::move(rail));
208 }
209
210 // Create Configuration for Device
211 std::optional<double> volts{};
212 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
213 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
214 std::vector<std::unique_ptr<Action>> actions{};
215 actions.emplace_back(std::move(action));
216 std::unique_ptr<Configuration> configuration =
217 std::make_unique<Configuration>(volts, std::move(actions));
218
219 // Create Device
220 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
221 std::unique_ptr<PresenceDetection> presenceDetection{};
222 std::unique_ptr<Device> device = std::make_unique<Device>(
223 "reg1", true, "/system/chassis/motherboard/reg1",
224 std::move(i2cInterface), std::move(presenceDetection),
225 std::move(configuration), std::move(rails));
226 Device* devicePtr = device.get();
227
228 // Create Chassis that contains Device
229 std::vector<std::unique_ptr<Device>> devices{};
230 devices.emplace_back(std::move(device));
231 std::unique_ptr<Chassis> chassis =
232 std::make_unique<Chassis>(1, std::move(devices));
233 Chassis* chassisPtr = chassis.get();
234
235 // Create System that contains Chassis
236 std::vector<std::unique_ptr<Rule>> rules{};
237 std::vector<std::unique_ptr<Chassis>> chassisVec{};
238 chassisVec.emplace_back(std::move(chassis));
239 System system{std::move(rules), std::move(chassisVec)};
240
241 // Call configure(). For the Device and both Rails, should execute the
242 // Configuration and log a debug message.
243 journal::clear();
244 devicePtr->configure(system, *chassisPtr);
245 std::vector<std::string> expectedDebugMessages{
Shawn McCarney525e20c2020-04-14 11:05:39 -0500246 "Configuring reg1", "Configuring vdd0: volts=1.300000",
247 "Configuring vio0: volts=3.200000"};
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500248 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
249 EXPECT_EQ(journal::getErrMessages().size(), 0);
250 }
251}
252
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500253TEST(DeviceTests, GetConfiguration)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500254{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500255 // Test where Configuration was not specified in constructor
256 {
257 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
258 std::move(createI2CInterface())};
259 EXPECT_EQ(device.getConfiguration(), nullptr);
260 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600261
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500262 // Test where Configuration was specified in constructor
263 {
264 std::unique_ptr<PresenceDetection> presenceDetection{};
265
266 // Create Configuration
267 std::optional<double> volts{3.2};
268 std::vector<std::unique_ptr<Action>> actions{};
269 actions.push_back(std::make_unique<MockAction>());
270 actions.push_back(std::make_unique<MockAction>());
271 std::unique_ptr<Configuration> configuration =
272 std::make_unique<Configuration>(volts, std::move(actions));
273
274 // Create Device
275 Device device{"vdd_reg",
276 true,
277 "/system/chassis/motherboard/reg2",
278 std::move(createI2CInterface()),
279 std::move(presenceDetection),
280 std::move(configuration)};
281 EXPECT_NE(device.getConfiguration(), nullptr);
282 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true);
283 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2);
284 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
285 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600286}
287
288TEST(DeviceTests, GetFRU)
289{
290 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
291 std::move(createI2CInterface())};
292 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg2");
293}
294
295TEST(DeviceTests, GetI2CInterface)
296{
297 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
298 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
299 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
300 std::move(i2cInterface)};
301 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
Shawn McCarneya2461b32019-10-24 18:53:01 -0500302}
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500303
304TEST(DeviceTests, GetID)
305{
306 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
307 std::move(createI2CInterface())};
308 EXPECT_EQ(device.getID(), "vdd_reg");
309}
310
311TEST(DeviceTests, GetPresenceDetection)
312{
313 // Test where PresenceDetection was not specified in constructor
314 {
315 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
316 std::move(createI2CInterface())};
317 EXPECT_EQ(device.getPresenceDetection(), nullptr);
318 }
319
320 // Test where PresenceDetection was specified in constructor
321 {
322 // Create PresenceDetection
323 std::vector<std::unique_ptr<Action>> actions{};
324 actions.push_back(std::make_unique<MockAction>());
325 std::unique_ptr<PresenceDetection> presenceDetection =
326 std::make_unique<PresenceDetection>(std::move(actions));
327
328 // Create Device
329 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
330 std::move(createI2CInterface()),
331 std::move(presenceDetection)};
332 EXPECT_NE(device.getPresenceDetection(), nullptr);
333 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
334 }
335}
336
337TEST(DeviceTests, GetRails)
338{
339 // Test where no rails were specified in constructor
340 {
341 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
342 std::move(createI2CInterface())};
343 EXPECT_EQ(device.getRails().size(), 0);
344 }
345
346 // Test where rails were specified in constructor
347 {
348 std::unique_ptr<PresenceDetection> presenceDetection{};
349 std::unique_ptr<Configuration> configuration{};
350
351 // Create vector of Rail objects
352 std::vector<std::unique_ptr<Rail>> rails{};
353 rails.push_back(std::make_unique<Rail>("vdd0"));
354 rails.push_back(std::make_unique<Rail>("vdd1"));
355
356 // Create Device
357 Device device{"vdd_reg",
358 false,
359 "/system/chassis/motherboard/reg2",
360 std::move(createI2CInterface()),
361 std::move(presenceDetection),
362 std::move(configuration),
363 std::move(rails)};
364 EXPECT_EQ(device.getRails().size(), 2);
365 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0");
366 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1");
367 }
368}
369
370TEST(DeviceTests, IsRegulator)
371{
372 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
373 std::move(createI2CInterface())};
374 EXPECT_EQ(device.isRegulator(), false);
375}