blob: 089e6eeeb633f225223132bbc73cc0bb94f40391 [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 McCarney4bf310e2020-03-10 17:48:11 -050016#include "action.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050017#include "chassis.hpp"
Shawn McCarney4bf310e2020-03-10 17:48:11 -050018#include "configuration.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050019#include "device.hpp"
20#include "i2c_interface.hpp"
Shawn McCarney4bf310e2020-03-10 17:48:11 -050021#include "mock_action.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050022#include "mock_journal.hpp"
Bob King23243f82020-07-29 10:38:57 +080023#include "mock_services.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050024#include "mocked_i2c_interface.hpp"
Bob King7b743432020-06-22 17:35:04 +080025#include "pmbus_read_sensor_action.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050026#include "presence_detection.hpp"
Shawn McCarneya2461b32019-10-24 18:53:01 -050027#include "rail.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050028#include "rule.hpp"
Shawn McCarney4bf310e2020-03-10 17:48:11 -050029#include "sensor_monitoring.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050030#include "system.hpp"
Shawn McCarney4bf310e2020-03-10 17:48:11 -050031
32#include <memory>
33#include <optional>
34#include <utility>
35#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;
41
Bob King7b743432020-06-22 17:35:04 +080042using ::testing::A;
Shawn McCarney779b9562020-04-13 17:05:45 -050043using ::testing::Return;
Bob King7b743432020-06-22 17:35:04 +080044using ::testing::TypedEq;
Shawn McCarney779b9562020-04-13 17:05:45 -050045
Shawn McCarneya2461b32019-10-24 18:53:01 -050046TEST(RailTests, Constructor)
47{
Shawn McCarney4bf310e2020-03-10 17:48:11 -050048 // Test where only required parameters are specified
49 {
50 Rail rail{"vdd0"};
51 EXPECT_EQ(rail.getID(), "vdd0");
52 EXPECT_EQ(rail.getConfiguration(), nullptr);
53 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
54 }
55
56 // Test where all parameters are specified
57 {
58 // Create Configuration
59 std::optional<double> volts{1.3};
60 std::vector<std::unique_ptr<Action>> actions{};
61 actions.push_back(std::make_unique<MockAction>());
62 actions.push_back(std::make_unique<MockAction>());
63 std::unique_ptr<Configuration> configuration =
64 std::make_unique<Configuration>(volts, std::move(actions));
65
66 // Create SensorMonitoring
67 actions.clear();
68 actions.push_back(std::make_unique<MockAction>());
69 std::unique_ptr<SensorMonitoring> sensorMonitoring =
70 std::make_unique<SensorMonitoring>(std::move(actions));
71
72 // Create Rail
73 Rail rail{"vddr1", std::move(configuration),
74 std::move(sensorMonitoring)};
75 EXPECT_EQ(rail.getID(), "vddr1");
76 EXPECT_NE(rail.getConfiguration(), nullptr);
77 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
78 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 1.3);
79 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 2);
80 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
81 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 1);
82 }
83}
84
Shawn McCarney779b9562020-04-13 17:05:45 -050085TEST(RailTests, Configure)
86{
87 // Test where Configuration was not specified in constructor
88 {
Bob King5cfe5102020-07-30 16:26:18 +080089 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +080090 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +080091 MockJournal& journal = services.getMockJournal();
92 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
93 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +080094
Shawn McCarney779b9562020-04-13 17:05:45 -050095 // Create Rail
96 std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
97 Rail* railPtr = rail.get();
98
99 // Create Device that contains Rail
100 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
101 std::make_unique<i2c::MockedI2CInterface>();
102 std::unique_ptr<PresenceDetection> presenceDetection{};
103 std::unique_ptr<Configuration> deviceConfiguration{};
104 std::vector<std::unique_ptr<Rail>> rails{};
105 rails.emplace_back(std::move(rail));
106 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800107 "reg1", true,
108 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500109 std::move(i2cInterface), std::move(presenceDetection),
110 std::move(deviceConfiguration), std::move(rails));
111 Device* devicePtr = device.get();
112
113 // Create Chassis that contains Device
114 std::vector<std::unique_ptr<Device>> devices{};
115 devices.emplace_back(std::move(device));
116 std::unique_ptr<Chassis> chassis =
117 std::make_unique<Chassis>(1, std::move(devices));
118 Chassis* chassisPtr = chassis.get();
119
120 // Create System that contains Chassis
121 std::vector<std::unique_ptr<Rule>> rules{};
122 std::vector<std::unique_ptr<Chassis>> chassisVec{};
123 chassisVec.emplace_back(std::move(chassis));
124 System system{std::move(rules), std::move(chassisVec)};
125
Bob King5cfe5102020-07-30 16:26:18 +0800126 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800127 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500128 }
129
130 // Test where Configuration was specified in constructor
131 {
Bob King5cfe5102020-07-30 16:26:18 +0800132 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800133 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800134 MockJournal& journal = services.getMockJournal();
135 EXPECT_CALL(journal, logDebug("Configuring vddr1: volts=1.300000"))
136 .Times(1);
137 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800138
Shawn McCarney779b9562020-04-13 17:05:45 -0500139 // Create Configuration
140 std::optional<double> volts{1.3};
141 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
142 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
143 std::vector<std::unique_ptr<Action>> actions{};
144 actions.emplace_back(std::move(action));
145 std::unique_ptr<Configuration> configuration =
146 std::make_unique<Configuration>(volts, std::move(actions));
147
148 // Create Rail
149 std::unique_ptr<Rail> rail =
150 std::make_unique<Rail>("vddr1", std::move(configuration));
151 Rail* railPtr = rail.get();
152
153 // Create Device that contains Rail
154 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
155 std::make_unique<i2c::MockedI2CInterface>();
156 std::unique_ptr<PresenceDetection> presenceDetection{};
157 std::unique_ptr<Configuration> deviceConfiguration{};
158 std::vector<std::unique_ptr<Rail>> rails{};
159 rails.emplace_back(std::move(rail));
160 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800161 "reg1", true,
162 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500163 std::move(i2cInterface), std::move(presenceDetection),
164 std::move(deviceConfiguration), std::move(rails));
165 Device* devicePtr = device.get();
166
167 // Create Chassis that contains Device
168 std::vector<std::unique_ptr<Device>> devices{};
169 devices.emplace_back(std::move(device));
170 std::unique_ptr<Chassis> chassis =
171 std::make_unique<Chassis>(1, std::move(devices));
172 Chassis* chassisPtr = chassis.get();
173
174 // Create System that contains Chassis
175 std::vector<std::unique_ptr<Rule>> rules{};
176 std::vector<std::unique_ptr<Chassis>> chassisVec{};
177 chassisVec.emplace_back(std::move(chassis));
178 System system{std::move(rules), std::move(chassisVec)};
179
Bob King5cfe5102020-07-30 16:26:18 +0800180 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800181 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500182 }
183}
184
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500185TEST(RailTests, GetConfiguration)
186{
187 // Test where Configuration was not specified in constructor
188 {
189 Rail rail{"vdd0"};
190 EXPECT_EQ(rail.getConfiguration(), nullptr);
191 }
192
193 // Test where Configuration was specified in constructor
194 {
195 // Create Configuration
196 std::optional<double> volts{3.2};
197 std::vector<std::unique_ptr<Action>> actions{};
198 actions.push_back(std::make_unique<MockAction>());
199 std::unique_ptr<Configuration> configuration =
200 std::make_unique<Configuration>(volts, std::move(actions));
201
202 // Create Rail
203 Rail rail{"vddr1", std::move(configuration)};
204 EXPECT_NE(rail.getConfiguration(), nullptr);
205 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
206 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 3.2);
207 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 1);
208 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500209}
210
Shawn McCarney4afb2852019-10-27 18:28:53 -0500211TEST(RailTests, GetID)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500212{
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500213 Rail rail{"vio2"};
Shawn McCarney4afb2852019-10-27 18:28:53 -0500214 EXPECT_EQ(rail.getID(), "vio2");
Shawn McCarneya2461b32019-10-24 18:53:01 -0500215}
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500216
Bob King7b743432020-06-22 17:35:04 +0800217TEST(RailTests, MonitorSensors)
218{
219 // Test where SensorMonitoring was not specified in constructor
220 {
Bob King8a552922020-08-05 17:02:31 +0800221 // Create mock services. No logging should occur.
222 MockServices services{};
223 MockJournal& journal = services.getMockJournal();
224 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
225 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
226
Bob King7b743432020-06-22 17:35:04 +0800227 // Create mock I2CInterface. A two-byte read should NOT occur.
228 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
229 std::make_unique<i2c::MockedI2CInterface>();
230 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint16_t&>())).Times(0);
231
232 // Create Rail
233 std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
234 Rail* railPtr = rail.get();
235
236 // Create Device that contains Rail
237 std::unique_ptr<PresenceDetection> presenceDetection{};
238 std::unique_ptr<Configuration> deviceConfiguration{};
239 std::vector<std::unique_ptr<Rail>> rails{};
240 rails.emplace_back(std::move(rail));
241 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800242 "reg1", true,
243 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800244 std::move(i2cInterface), std::move(presenceDetection),
245 std::move(deviceConfiguration), std::move(rails));
246 Device* devicePtr = device.get();
247
248 // Create Chassis that contains Device
249 std::vector<std::unique_ptr<Device>> devices{};
250 devices.emplace_back(std::move(device));
251 std::unique_ptr<Chassis> chassis =
252 std::make_unique<Chassis>(1, std::move(devices));
253 Chassis* chassisPtr = chassis.get();
254
255 // Create System that contains Chassis
256 std::vector<std::unique_ptr<Rule>> rules{};
257 std::vector<std::unique_ptr<Chassis>> chassisVec{};
258 chassisVec.emplace_back(std::move(chassis));
259 System system{std::move(rules), std::move(chassisVec)};
260
Bob King8a552922020-08-05 17:02:31 +0800261 // Call monitorSensors().
262 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800263 }
264
265 // Test where SensorMonitoring was specified in constructor
266 {
Bob King8a552922020-08-05 17:02:31 +0800267 // Create mock services. No logging should occur.
268 MockServices services{};
269 MockJournal& journal = services.getMockJournal();
270 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
271 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
272
Bob King7b743432020-06-22 17:35:04 +0800273 // Create PMBusReadSensorAction
274 pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
275 uint8_t command = 0x8C;
276 pmbus_utils::SensorDataFormat format{
277 pmbus_utils::SensorDataFormat::linear_11};
278 std::optional<int8_t> exponent{};
279 std::unique_ptr<PMBusReadSensorAction> action =
280 std::make_unique<PMBusReadSensorAction>(type, command, format,
281 exponent);
282
283 // Create mock I2CInterface. A two-byte read should occur.
284 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
285 std::make_unique<i2c::MockedI2CInterface>();
286 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
287 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
288 .Times(1);
289
290 // Create SensorMonitoring
291 std::vector<std::unique_ptr<Action>> actions{};
292 actions.emplace_back(std::move(action));
293 std::unique_ptr<SensorMonitoring> sensorMonitoring =
294 std::make_unique<SensorMonitoring>(std::move(actions));
295
296 // Create Rail
297 std::unique_ptr<Configuration> configuration{};
298 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
299 "vddr1", std::move(configuration), std::move(sensorMonitoring));
300 Rail* railPtr = rail.get();
301
302 // Create Device that contains Rail
303 std::unique_ptr<PresenceDetection> presenceDetection{};
304 std::unique_ptr<Configuration> deviceConfiguration{};
305 std::vector<std::unique_ptr<Rail>> rails{};
306 rails.emplace_back(std::move(rail));
307 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800308 "reg1", true,
309 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800310 std::move(i2cInterface), std::move(presenceDetection),
311 std::move(deviceConfiguration), std::move(rails));
312 Device* devicePtr = device.get();
313
314 // Create Chassis that contains Device
315 std::vector<std::unique_ptr<Device>> devices{};
316 devices.emplace_back(std::move(device));
317 std::unique_ptr<Chassis> chassis =
318 std::make_unique<Chassis>(1, std::move(devices));
319 Chassis* chassisPtr = chassis.get();
320
321 // Create System that contains Chassis
322 std::vector<std::unique_ptr<Rule>> rules{};
323 std::vector<std::unique_ptr<Chassis>> chassisVec{};
324 chassisVec.emplace_back(std::move(chassis));
325 System system{std::move(rules), std::move(chassisVec)};
326
327 // Call monitorSensors().
Bob King8a552922020-08-05 17:02:31 +0800328 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800329 }
330}
331
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500332TEST(RailTests, GetSensorMonitoring)
333{
334 // Test where SensorMonitoring was not specified in constructor
335 {
336 Rail rail{"vdd0", nullptr, nullptr};
337 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
338 }
339
340 // Test where SensorMonitoring was specified in constructor
341 {
342 std::unique_ptr<Configuration> configuration{};
343
344 // Create SensorMonitoring
345 std::vector<std::unique_ptr<Action>> actions{};
346 actions.push_back(std::make_unique<MockAction>());
347 actions.push_back(std::make_unique<MockAction>());
348 std::unique_ptr<SensorMonitoring> sensorMonitoring =
349 std::make_unique<SensorMonitoring>(std::move(actions));
350
351 // Create Rail
352 Rail rail{"vddr1", std::move(configuration),
353 std::move(sensorMonitoring)};
354 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
355 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 2);
356 }
357}