blob: d852a06bb58afaa62d014cd2afc05ab4291cfe0c [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"
Shawn McCarney17bac892021-05-08 07:55:52 -050023#include "mock_sensors.hpp"
Bob King23243f82020-07-29 10:38:57 +080024#include "mock_services.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050025#include "mocked_i2c_interface.hpp"
26#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 McCarneycb3f6a62021-04-30 10:54:30 -050047static const std::string chassisInvPath{
48 "/xyz/openbmc_project/inventory/system/chassis"};
49
Shawn McCarneya2461b32019-10-24 18:53:01 -050050TEST(RailTests, Constructor)
51{
Shawn McCarney4bf310e2020-03-10 17:48:11 -050052 // Test where only required parameters are specified
53 {
54 Rail rail{"vdd0"};
55 EXPECT_EQ(rail.getID(), "vdd0");
56 EXPECT_EQ(rail.getConfiguration(), nullptr);
57 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
58 }
59
60 // Test where all parameters are specified
61 {
62 // Create Configuration
63 std::optional<double> volts{1.3};
64 std::vector<std::unique_ptr<Action>> actions{};
65 actions.push_back(std::make_unique<MockAction>());
66 actions.push_back(std::make_unique<MockAction>());
67 std::unique_ptr<Configuration> configuration =
68 std::make_unique<Configuration>(volts, std::move(actions));
69
70 // Create SensorMonitoring
71 actions.clear();
72 actions.push_back(std::make_unique<MockAction>());
73 std::unique_ptr<SensorMonitoring> sensorMonitoring =
74 std::make_unique<SensorMonitoring>(std::move(actions));
75
76 // Create Rail
77 Rail rail{"vddr1", std::move(configuration),
78 std::move(sensorMonitoring)};
79 EXPECT_EQ(rail.getID(), "vddr1");
80 EXPECT_NE(rail.getConfiguration(), nullptr);
81 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
82 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 1.3);
83 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 2);
84 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
85 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 1);
86 }
87}
88
Shawn McCarney779b9562020-04-13 17:05:45 -050089TEST(RailTests, Configure)
90{
91 // Test where Configuration was not specified in constructor
92 {
Bob King5cfe5102020-07-30 16:26:18 +080093 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +080094 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +080095 MockJournal& journal = services.getMockJournal();
96 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
97 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +080098
Shawn McCarney779b9562020-04-13 17:05:45 -050099 // Create Rail
100 std::unique_ptr<Rail> rail = std::make_unique<Rail>("vdd0");
101 Rail* railPtr = rail.get();
102
103 // Create Device that contains Rail
104 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
105 std::make_unique<i2c::MockedI2CInterface>();
106 std::unique_ptr<PresenceDetection> presenceDetection{};
107 std::unique_ptr<Configuration> deviceConfiguration{};
108 std::vector<std::unique_ptr<Rail>> rails{};
109 rails.emplace_back(std::move(rail));
110 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800111 "reg1", true,
112 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500113 std::move(i2cInterface), std::move(presenceDetection),
114 std::move(deviceConfiguration), std::move(rails));
115 Device* devicePtr = device.get();
116
117 // Create Chassis that contains Device
118 std::vector<std::unique_ptr<Device>> devices{};
119 devices.emplace_back(std::move(device));
120 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500121 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney779b9562020-04-13 17:05:45 -0500122 Chassis* chassisPtr = chassis.get();
123
124 // Create System that contains Chassis
125 std::vector<std::unique_ptr<Rule>> rules{};
126 std::vector<std::unique_ptr<Chassis>> chassisVec{};
127 chassisVec.emplace_back(std::move(chassis));
128 System system{std::move(rules), std::move(chassisVec)};
129
Bob King5cfe5102020-07-30 16:26:18 +0800130 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800131 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500132 }
133
134 // Test where Configuration was specified in constructor
135 {
Bob King5cfe5102020-07-30 16:26:18 +0800136 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800137 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800138 MockJournal& journal = services.getMockJournal();
139 EXPECT_CALL(journal, logDebug("Configuring vddr1: volts=1.300000"))
140 .Times(1);
141 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800142
Shawn McCarney779b9562020-04-13 17:05:45 -0500143 // Create Configuration
144 std::optional<double> volts{1.3};
145 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
146 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
147 std::vector<std::unique_ptr<Action>> actions{};
148 actions.emplace_back(std::move(action));
149 std::unique_ptr<Configuration> configuration =
150 std::make_unique<Configuration>(volts, std::move(actions));
151
152 // Create Rail
153 std::unique_ptr<Rail> rail =
154 std::make_unique<Rail>("vddr1", std::move(configuration));
155 Rail* railPtr = rail.get();
156
157 // Create Device that contains Rail
158 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
159 std::make_unique<i2c::MockedI2CInterface>();
160 std::unique_ptr<PresenceDetection> presenceDetection{};
161 std::unique_ptr<Configuration> deviceConfiguration{};
162 std::vector<std::unique_ptr<Rail>> rails{};
163 rails.emplace_back(std::move(rail));
164 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800165 "reg1", true,
166 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney779b9562020-04-13 17:05:45 -0500167 std::move(i2cInterface), std::move(presenceDetection),
168 std::move(deviceConfiguration), std::move(rails));
169 Device* devicePtr = device.get();
170
171 // Create Chassis that contains Device
172 std::vector<std::unique_ptr<Device>> devices{};
173 devices.emplace_back(std::move(device));
174 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500175 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney779b9562020-04-13 17:05:45 -0500176 Chassis* chassisPtr = chassis.get();
177
178 // Create System that contains Chassis
179 std::vector<std::unique_ptr<Rule>> rules{};
180 std::vector<std::unique_ptr<Chassis>> chassisVec{};
181 chassisVec.emplace_back(std::move(chassis));
182 System system{std::move(rules), std::move(chassisVec)};
183
Bob King5cfe5102020-07-30 16:26:18 +0800184 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800185 railPtr->configure(services, system, *chassisPtr, *devicePtr);
Shawn McCarney779b9562020-04-13 17:05:45 -0500186 }
187}
188
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500189TEST(RailTests, GetConfiguration)
190{
191 // Test where Configuration was not specified in constructor
192 {
193 Rail rail{"vdd0"};
194 EXPECT_EQ(rail.getConfiguration(), nullptr);
195 }
196
197 // Test where Configuration was specified in constructor
198 {
199 // Create Configuration
200 std::optional<double> volts{3.2};
201 std::vector<std::unique_ptr<Action>> actions{};
202 actions.push_back(std::make_unique<MockAction>());
203 std::unique_ptr<Configuration> configuration =
204 std::make_unique<Configuration>(volts, std::move(actions));
205
206 // Create Rail
207 Rail rail{"vddr1", std::move(configuration)};
208 EXPECT_NE(rail.getConfiguration(), nullptr);
209 EXPECT_EQ(rail.getConfiguration()->getVolts().has_value(), true);
210 EXPECT_EQ(rail.getConfiguration()->getVolts().value(), 3.2);
211 EXPECT_EQ(rail.getConfiguration()->getActions().size(), 1);
212 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500213}
214
Shawn McCarney4afb2852019-10-27 18:28:53 -0500215TEST(RailTests, GetID)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500216{
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500217 Rail rail{"vio2"};
Shawn McCarney4afb2852019-10-27 18:28:53 -0500218 EXPECT_EQ(rail.getID(), "vio2");
Shawn McCarneya2461b32019-10-24 18:53:01 -0500219}
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500220
Bob King7b743432020-06-22 17:35:04 +0800221TEST(RailTests, MonitorSensors)
222{
223 // Test where SensorMonitoring was not specified in constructor
224 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500225 // Create mock services. No Sensors methods should be called.
Bob King8a552922020-08-05 17:02:31 +0800226 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500227 MockSensors& sensors = services.getMockSensors();
228 EXPECT_CALL(sensors, startRail).Times(0);
229 EXPECT_CALL(sensors, setValue).Times(0);
230 EXPECT_CALL(sensors, endRail).Times(0);
Bob King7b743432020-06-22 17:35:04 +0800231
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
Shawn McCarney17bac892021-05-08 07:55:52 -0500237 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
238 std::make_unique<i2c::MockedI2CInterface>();
Bob King7b743432020-06-22 17:35:04 +0800239 std::unique_ptr<PresenceDetection> presenceDetection{};
240 std::unique_ptr<Configuration> deviceConfiguration{};
241 std::vector<std::unique_ptr<Rail>> rails{};
242 rails.emplace_back(std::move(rail));
243 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800244 "reg1", true,
245 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800246 std::move(i2cInterface), std::move(presenceDetection),
247 std::move(deviceConfiguration), std::move(rails));
248 Device* devicePtr = device.get();
249
250 // Create Chassis that contains Device
251 std::vector<std::unique_ptr<Device>> devices{};
252 devices.emplace_back(std::move(device));
253 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500254 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Bob King7b743432020-06-22 17:35:04 +0800255 Chassis* chassisPtr = chassis.get();
256
257 // Create System that contains Chassis
258 std::vector<std::unique_ptr<Rule>> rules{};
259 std::vector<std::unique_ptr<Chassis>> chassisVec{};
260 chassisVec.emplace_back(std::move(chassis));
261 System system{std::move(rules), std::move(chassisVec)};
262
Shawn McCarney17bac892021-05-08 07:55:52 -0500263 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800264 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800265 }
266
267 // Test where SensorMonitoring was specified in constructor
268 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500269 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800270 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500271 MockSensors& sensors = services.getMockSensors();
272 EXPECT_CALL(sensors,
273 startRail("vddr1",
274 "/xyz/openbmc_project/inventory/system/chassis/"
275 "motherboard/reg1",
276 chassisInvPath))
Bob King7b743432020-06-22 17:35:04 +0800277 .Times(1);
Shawn McCarney17bac892021-05-08 07:55:52 -0500278 EXPECT_CALL(sensors, setValue).Times(0);
279 EXPECT_CALL(sensors, endRail(false)).Times(1);
Bob King7b743432020-06-22 17:35:04 +0800280
281 // Create SensorMonitoring
Shawn McCarney17bac892021-05-08 07:55:52 -0500282 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
283 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
Bob King7b743432020-06-22 17:35:04 +0800284 std::vector<std::unique_ptr<Action>> actions{};
285 actions.emplace_back(std::move(action));
286 std::unique_ptr<SensorMonitoring> sensorMonitoring =
287 std::make_unique<SensorMonitoring>(std::move(actions));
288
289 // Create Rail
290 std::unique_ptr<Configuration> configuration{};
291 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
292 "vddr1", std::move(configuration), std::move(sensorMonitoring));
293 Rail* railPtr = rail.get();
294
295 // Create Device that contains Rail
Shawn McCarney17bac892021-05-08 07:55:52 -0500296 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
297 std::make_unique<i2c::MockedI2CInterface>();
Bob King7b743432020-06-22 17:35:04 +0800298 std::unique_ptr<PresenceDetection> presenceDetection{};
299 std::unique_ptr<Configuration> deviceConfiguration{};
300 std::vector<std::unique_ptr<Rail>> rails{};
301 rails.emplace_back(std::move(rail));
302 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800303 "reg1", true,
304 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King7b743432020-06-22 17:35:04 +0800305 std::move(i2cInterface), std::move(presenceDetection),
306 std::move(deviceConfiguration), std::move(rails));
307 Device* devicePtr = device.get();
308
309 // Create Chassis that contains Device
310 std::vector<std::unique_ptr<Device>> devices{};
311 devices.emplace_back(std::move(device));
312 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500313 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Bob King7b743432020-06-22 17:35:04 +0800314 Chassis* chassisPtr = chassis.get();
315
316 // Create System that contains Chassis
317 std::vector<std::unique_ptr<Rule>> rules{};
318 std::vector<std::unique_ptr<Chassis>> chassisVec{};
319 chassisVec.emplace_back(std::move(chassis));
320 System system{std::move(rules), std::move(chassisVec)};
321
Shawn McCarney17bac892021-05-08 07:55:52 -0500322 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800323 railPtr->monitorSensors(services, system, *chassisPtr, *devicePtr);
Bob King7b743432020-06-22 17:35:04 +0800324 }
325}
326
Shawn McCarney4bf310e2020-03-10 17:48:11 -0500327TEST(RailTests, GetSensorMonitoring)
328{
329 // Test where SensorMonitoring was not specified in constructor
330 {
331 Rail rail{"vdd0", nullptr, nullptr};
332 EXPECT_EQ(rail.getSensorMonitoring(), nullptr);
333 }
334
335 // Test where SensorMonitoring was specified in constructor
336 {
337 std::unique_ptr<Configuration> configuration{};
338
339 // Create SensorMonitoring
340 std::vector<std::unique_ptr<Action>> actions{};
341 actions.push_back(std::make_unique<MockAction>());
342 actions.push_back(std::make_unique<MockAction>());
343 std::unique_ptr<SensorMonitoring> sensorMonitoring =
344 std::make_unique<SensorMonitoring>(std::move(actions));
345
346 // Create Rail
347 Rail rail{"vddr1", std::move(configuration),
348 std::move(sensorMonitoring)};
349 EXPECT_NE(rail.getSensorMonitoring(), nullptr);
350 EXPECT_EQ(rail.getSensorMonitoring()->getActions().size(), 2);
351 }
352}