blob: f0d95293b599248ae6c74b54ea1d30113da900ce [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 McCarney2f9e14f2021-04-29 02:45:18 -050030#include "sensors.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050031#include "system.hpp"
Shawn McCarney4bf310e2020-03-10 17:48:11 -050032
33#include <memory>
34#include <optional>
35#include <utility>
36#include <vector>
Shawn McCarneya2461b32019-10-24 18:53:01 -050037
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050038#include <gmock/gmock.h>
Shawn McCarneya2461b32019-10-24 18:53:01 -050039#include <gtest/gtest.h>
40
41using namespace phosphor::power::regulators;
42
Bob King7b743432020-06-22 17:35:04 +080043using ::testing::A;
Shawn McCarney779b9562020-04-13 17:05:45 -050044using ::testing::Return;
Bob King7b743432020-06-22 17:35:04 +080045using ::testing::TypedEq;
Shawn McCarney779b9562020-04-13 17:05:45 -050046
Shawn McCarneya2461b32019-10-24 18:53:01 -050047TEST(RailTests, Constructor)
48{
Shawn McCarney4bf310e2020-03-10 17:48:11 -050049 // Test where only required parameters are specified
50 {
51 Rail rail{"vdd0"};
52 EXPECT_EQ(rail.getID(), "vdd0");
53 EXPECT_EQ(rail.getConfiguration(), nullptr);
54 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
55 }
56
57 // Test where all parameters are specified
58 {
59 // Create Configuration
60 std::optional<double> volts{1.3};
61 std::vector<std::unique_ptr<Action>> actions{};
62 actions.push_back(std::make_unique<MockAction>());
63 actions.push_back(std::make_unique<MockAction>());
64 std::unique_ptr<Configuration> configuration =
65 std::make_unique<Configuration>(volts, std::move(actions));
66
67 // Create SensorMonitoring
68 actions.clear();
69 actions.push_back(std::make_unique<MockAction>());
70 std::unique_ptr<SensorMonitoring> sensorMonitoring =
71 std::make_unique<SensorMonitoring>(std::move(actions));
72
73 // Create Rail
74 Rail rail{"vddr1", std::move(configuration),
75 std::move(sensorMonitoring)};
76 EXPECT_EQ(rail.getID(), "vddr1");
77 EXPECT_NE(rail.getConfiguration(), nullptr);
78 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
79 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 1.3);
80 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 2);
81 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
82 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 1);
83 }
84}
85
Shawn McCarney779b9562020-04-13 17:05:45 -050086TEST(RailTests, Configure)
87{
88 // Test where Configuration was not specified in constructor
89 {
Bob King5cfe5102020-07-30 16:26:18 +080090 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +080091 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +080092 MockJournal& journal = services.getMockJournal();
93 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
94 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +080095
Shawn McCarney779b9562020-04-13 17:05:45 -050096 // Create Rail
97 std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
98 Rail* railPtr = rail.get();
99
100 // Create Device that contains Rail
101 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
102 std::make_unique<i2c::MockedI2CInterface>();
103 std::unique_ptr<PresenceDetection> presenceDetection{};
104 std::unique_ptr<Configuration> deviceConfiguration{};
105 std::vector<std::unique_ptr<Rail>> rails{};
106 rails.emplace_back(std::move(rail));
107 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800108 "reg1", true,
109 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500110 std::move(i2cInterface), std::move(presenceDetection),
111 std::move(deviceConfiguration), std::move(rails));
112 Device* devicePtr = device.get();
113
114 // Create Chassis that contains Device
115 std::vector<std::unique_ptr<Device>> devices{};
116 devices.emplace_back(std::move(device));
117 std::unique_ptr<Chassis> chassis =
118 std::make_unique<Chassis>(1, std::move(devices));
119 Chassis* chassisPtr = chassis.get();
120
121 // Create System that contains Chassis
122 std::vector<std::unique_ptr<Rule>> rules{};
123 std::vector<std::unique_ptr<Chassis>> chassisVec{};
124 chassisVec.emplace_back(std::move(chassis));
125 System system{std::move(rules), std::move(chassisVec)};
126
Bob King5cfe5102020-07-30 16:26:18 +0800127 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800128 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500129 }
130
131 // Test where Configuration was specified in constructor
132 {
Bob King5cfe5102020-07-30 16:26:18 +0800133 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800134 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800135 MockJournal& journal = services.getMockJournal();
136 EXPECT_CALL(journal, logDebug("Configuring vddr1: volts=1.300000"))
137 .Times(1);
138 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800139
Shawn McCarney779b9562020-04-13 17:05:45 -0500140 // Create Configuration
141 std::optional<double> volts{1.3};
142 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
143 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
144 std::vector<std::unique_ptr<Action>> actions{};
145 actions.emplace_back(std::move(action));
146 std::unique_ptr<Configuration> configuration =
147 std::make_unique<Configuration>(volts, std::move(actions));
148
149 // Create Rail
150 std::unique_ptr<Rail> rail =
151 std::make_unique<Rail>("vddr1", std::move(configuration));
152 Rail* railPtr = rail.get();
153
154 // Create Device that contains Rail
155 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
156 std::make_unique<i2c::MockedI2CInterface>();
157 std::unique_ptr<PresenceDetection> presenceDetection{};
158 std::unique_ptr<Configuration> deviceConfiguration{};
159 std::vector<std::unique_ptr<Rail>> rails{};
160 rails.emplace_back(std::move(rail));
161 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800162 "reg1", true,
163 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500164 std::move(i2cInterface), std::move(presenceDetection),
165 std::move(deviceConfiguration), std::move(rails));
166 Device* devicePtr = device.get();
167
168 // Create Chassis that contains Device
169 std::vector<std::unique_ptr<Device>> devices{};
170 devices.emplace_back(std::move(device));
171 std::unique_ptr<Chassis> chassis =
172 std::make_unique<Chassis>(1, 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
Bob King5cfe5102020-07-30 16:26:18 +0800181 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800182 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500183 }
184}
185
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500186TEST(RailTests, GetConfiguration)
187{
188 // Test where Configuration was not specified in constructor
189 {
190 Rail rail{"vdd0"};
191 EXPECT_EQ(rail.getConfiguration(), nullptr);
192 }
193
194 // Test where Configuration was specified in constructor
195 {
196 // Create Configuration
197 std::optional<double> volts{3.2};
198 std::vector<std::unique_ptr<Action>> actions{};
199 actions.push_back(std::make_unique<MockAction>());
200 std::unique_ptr<Configuration> configuration =
201 std::make_unique<Configuration>(volts, std::move(actions));
202
203 // Create Rail
204 Rail rail{"vddr1", std::move(configuration)};
205 EXPECT_NE(rail.getConfiguration(), nullptr);
206 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
207 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 3.2);
208 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 1);
209 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500210}
211
Shawn McCarney4afb2852019-10-27 18:28:53 -0500212TEST(RailTests, GetID)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500213{
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500214 Rail rail{"vio2"};
Shawn McCarney4afb2852019-10-27 18:28:53 -0500215 EXPECT_EQ(rail.getID(), "vio2");
Shawn McCarneya2461b32019-10-24 18:53:01 -0500216}
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500217
Bob King7b743432020-06-22 17:35:04 +0800218TEST(RailTests, MonitorSensors)
219{
220 // Test where SensorMonitoring was not specified in constructor
221 {
Bob King8a552922020-08-05 17:02:31 +0800222 // Create mock services. No logging should occur.
223 MockServices services{};
224 MockJournal& journal = services.getMockJournal();
225 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
226 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
227
Bob King7b743432020-06-22 17:35:04 +0800228 // Create mock I2CInterface. A two-byte read should NOT occur.
229 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
230 std::make_unique<i2c::MockedI2CInterface>();
231 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint16_t&>())).Times(0);
232
233 // Create Rail
234 std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
235 Rail* railPtr = rail.get();
236
237 // Create Device that contains Rail
238 std::unique_ptr<PresenceDetection> presenceDetection{};
239 std::unique_ptr<Configuration> deviceConfiguration{};
240 std::vector<std::unique_ptr<Rail>> rails{};
241 rails.emplace_back(std::move(rail));
242 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800243 "reg1", true,
244 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800245 std::move(i2cInterface), std::move(presenceDetection),
246 std::move(deviceConfiguration), std::move(rails));
247 Device* devicePtr = device.get();
248
249 // Create Chassis that contains Device
250 std::vector<std::unique_ptr<Device>> devices{};
251 devices.emplace_back(std::move(device));
252 std::unique_ptr<Chassis> chassis =
253 std::make_unique<Chassis>(1, std::move(devices));
254 Chassis* chassisPtr = chassis.get();
255
256 // Create System that contains Chassis
257 std::vector<std::unique_ptr<Rule>> rules{};
258 std::vector<std::unique_ptr<Chassis>> chassisVec{};
259 chassisVec.emplace_back(std::move(chassis));
260 System system{std::move(rules), std::move(chassisVec)};
261
Bob King8a552922020-08-05 17:02:31 +0800262 // Call monitorSensors().
263 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800264 }
265
266 // Test where SensorMonitoring was specified in constructor
267 {
Bob King8a552922020-08-05 17:02:31 +0800268 // Create mock services. No logging should occur.
269 MockServices services{};
270 MockJournal& journal = services.getMockJournal();
271 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
272 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
273
Bob King7b743432020-06-22 17:35:04 +0800274 // Create PMBusReadSensorAction
Shawn McCarney2f9e14f2021-04-29 02:45:18 -0500275 SensorType type{SensorType::iout};
Bob King7b743432020-06-22 17:35:04 +0800276 uint8_t command = 0x8C;
277 pmbus_utils::SensorDataFormat format{
278 pmbus_utils::SensorDataFormat::linear_11};
279 std::optional<int8_t> exponent{};
280 std::unique_ptr<PMBusReadSensorAction> action =
281 std::make_unique<PMBusReadSensorAction>(type, command, format,
282 exponent);
283
284 // Create mock I2CInterface. A two-byte read should occur.
285 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
286 std::make_unique<i2c::MockedI2CInterface>();
287 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
288 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
289 .Times(1);
290
291 // Create SensorMonitoring
292 std::vector<std::unique_ptr<Action>> actions{};
293 actions.emplace_back(std::move(action));
294 std::unique_ptr<SensorMonitoring> sensorMonitoring =
295 std::make_unique<SensorMonitoring>(std::move(actions));
296
297 // Create Rail
298 std::unique_ptr<Configuration> configuration{};
299 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
300 "vddr1", std::move(configuration), std::move(sensorMonitoring));
301 Rail* railPtr = rail.get();
302
303 // Create Device that contains Rail
304 std::unique_ptr<PresenceDetection> presenceDetection{};
305 std::unique_ptr<Configuration> deviceConfiguration{};
306 std::vector<std::unique_ptr<Rail>> rails{};
307 rails.emplace_back(std::move(rail));
308 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800309 "reg1", true,
310 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800311 std::move(i2cInterface), std::move(presenceDetection),
312 std::move(deviceConfiguration), std::move(rails));
313 Device* devicePtr = device.get();
314
315 // Create Chassis that contains Device
316 std::vector<std::unique_ptr<Device>> devices{};
317 devices.emplace_back(std::move(device));
318 std::unique_ptr<Chassis> chassis =
319 std::make_unique<Chassis>(1, std::move(devices));
320 Chassis* chassisPtr = chassis.get();
321
322 // Create System that contains Chassis
323 std::vector<std::unique_ptr<Rule>> rules{};
324 std::vector<std::unique_ptr<Chassis>> chassisVec{};
325 chassisVec.emplace_back(std::move(chassis));
326 System system{std::move(rules), std::move(chassisVec)};
327
328 // Call monitorSensors().
Bob King8a552922020-08-05 17:02:31 +0800329 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800330 }
331}
332
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500333TEST(RailTests, GetSensorMonitoring)
334{
335 // Test where SensorMonitoring was not specified in constructor
336 {
337 Rail rail{"vdd0", nullptr, nullptr};
338 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
339 }
340
341 // Test where SensorMonitoring was specified in constructor
342 {
343 std::unique_ptr<Configuration> configuration{};
344
345 // Create SensorMonitoring
346 std::vector<std::unique_ptr<Action>> actions{};
347 actions.push_back(std::make_unique<MockAction>());
348 actions.push_back(std::make_unique<MockAction>());
349 std::unique_ptr<SensorMonitoring> sensorMonitoring =
350 std::make_unique<SensorMonitoring>(std::move(actions));
351
352 // Create Rail
353 Rail rail{"vddr1", std::move(configuration),
354 std::move(sensorMonitoring)};
355 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
356 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 2);
357 }
358}