blob: 1ce065c23a096b9004f01af38a7d7f9d7b06a3ef [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"
28#include "sensor_monitoring.hpp"
29#include "system.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050030#include "test_utils.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060031
32#include <memory>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050033#include <optional>
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{
246 "Configuring reg1",
247 "Configuring vdd0: volts=1.300000",
248 "Configuring vio0: volts=3.200000",
249 };
250 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
251 EXPECT_EQ(journal::getErrMessages().size(), 0);
252 }
253}
254
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500255TEST(DeviceTests, GetConfiguration)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500256{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500257 // Test where Configuration was not specified in constructor
258 {
259 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
260 std::move(createI2CInterface())};
261 EXPECT_EQ(device.getConfiguration(), nullptr);
262 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600263
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500264 // Test where Configuration was specified in constructor
265 {
266 std::unique_ptr<PresenceDetection> presenceDetection{};
267
268 // Create Configuration
269 std::optional<double> volts{3.2};
270 std::vector<std::unique_ptr<Action>> actions{};
271 actions.push_back(std::make_unique<MockAction>());
272 actions.push_back(std::make_unique<MockAction>());
273 std::unique_ptr<Configuration> configuration =
274 std::make_unique<Configuration>(volts, std::move(actions));
275
276 // Create Device
277 Device device{"vdd_reg",
278 true,
279 "/system/chassis/motherboard/reg2",
280 std::move(createI2CInterface()),
281 std::move(presenceDetection),
282 std::move(configuration)};
283 EXPECT_NE(device.getConfiguration(), nullptr);
284 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true);
285 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2);
286 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
287 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600288}
289
290TEST(DeviceTests, GetFRU)
291{
292 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
293 std::move(createI2CInterface())};
294 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg2");
295}
296
297TEST(DeviceTests, GetI2CInterface)
298{
299 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
300 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
301 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
302 std::move(i2cInterface)};
303 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
Shawn McCarneya2461b32019-10-24 18:53:01 -0500304}
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500305
306TEST(DeviceTests, GetID)
307{
308 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
309 std::move(createI2CInterface())};
310 EXPECT_EQ(device.getID(), "vdd_reg");
311}
312
313TEST(DeviceTests, GetPresenceDetection)
314{
315 // Test where PresenceDetection was not specified in constructor
316 {
317 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
318 std::move(createI2CInterface())};
319 EXPECT_EQ(device.getPresenceDetection(), nullptr);
320 }
321
322 // Test where PresenceDetection was specified in constructor
323 {
324 // Create PresenceDetection
325 std::vector<std::unique_ptr<Action>> actions{};
326 actions.push_back(std::make_unique<MockAction>());
327 std::unique_ptr<PresenceDetection> presenceDetection =
328 std::make_unique<PresenceDetection>(std::move(actions));
329
330 // Create Device
331 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
332 std::move(createI2CInterface()),
333 std::move(presenceDetection)};
334 EXPECT_NE(device.getPresenceDetection(), nullptr);
335 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
336 }
337}
338
339TEST(DeviceTests, GetRails)
340{
341 // Test where no rails were specified in constructor
342 {
343 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
344 std::move(createI2CInterface())};
345 EXPECT_EQ(device.getRails().size(), 0);
346 }
347
348 // Test where rails were specified in constructor
349 {
350 std::unique_ptr<PresenceDetection> presenceDetection{};
351 std::unique_ptr<Configuration> configuration{};
352
353 // Create vector of Rail objects
354 std::vector<std::unique_ptr<Rail>> rails{};
355 rails.push_back(std::make_unique<Rail>("vdd0"));
356 rails.push_back(std::make_unique<Rail>("vdd1"));
357
358 // Create Device
359 Device device{"vdd_reg",
360 false,
361 "/system/chassis/motherboard/reg2",
362 std::move(createI2CInterface()),
363 std::move(presenceDetection),
364 std::move(configuration),
365 std::move(rails)};
366 EXPECT_EQ(device.getRails().size(), 2);
367 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0");
368 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1");
369 }
370}
371
372TEST(DeviceTests, IsRegulator)
373{
374 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
375 std::move(createI2CInterface())};
376 EXPECT_EQ(device.isRegulator(), false);
377}