blob: 31df5d67d7ead40afe39e4fc5ce78531c844459a [file] [log] [blame]
Shawn McCarneyc3991f12020-04-05 13:16:06 -05001/**
2 * Copyright © 2020 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 McCarney17bac892021-05-08 07:55:52 -050016#include "action.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050017#include "chassis.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050018#include "configuration.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050019#include "device.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050020#include "i2c_interface.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050021#include "id_map.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050022#include "mock_action.hpp"
Shawn McCarney2af52892020-04-14 11:54:45 -050023#include "mock_journal.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050024#include "mock_sensors.hpp"
Bob King23243f82020-07-29 10:38:57 +080025#include "mock_services.hpp"
Bob King8e2294d2020-07-14 17:41:31 +080026#include "mocked_i2c_interface.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050027#include "presence_detection.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050028#include "rail.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050029#include "rule.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050030#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050031#include "sensors.hpp"
Bob King5cfe5102020-07-30 16:26:18 +080032#include "services.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050033#include "system.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050034#include "test_utils.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050035
36#include <memory>
Shawn McCarneydb0b8332020-04-06 14:13:04 -050037#include <stdexcept>
Shawn McCarney2af52892020-04-14 11:54:45 -050038#include <string>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050039#include <utility>
40#include <vector>
41
Bob King8e2294d2020-07-14 17:41:31 +080042#include <gmock/gmock.h>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050043#include <gtest/gtest.h>
44
45using namespace phosphor::power::regulators;
Shawn McCarneydb0b8332020-04-06 14:13:04 -050046using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyc3991f12020-04-05 13:16:06 -050047
Bob King8e2294d2020-07-14 17:41:31 +080048using ::testing::A;
49using ::testing::Return;
50using ::testing::TypedEq;
51
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050052static const std::string chassisInvPath{
53 "/xyz/openbmc_project/inventory/system/chassis"};
54
Shawn McCarneyc3991f12020-04-05 13:16:06 -050055TEST(SystemTests, Constructor)
56{
57 // Create Rules
58 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050059 rules.emplace_back(createRule("set_voltage_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050060
61 // Create Chassis
62 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050063 std::vector<std::unique_ptr<Device>> devices{};
64 devices.emplace_back(createDevice("reg1", {"rail1"}));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050065 chassis.emplace_back(
66 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices)));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050067
68 // Create System
69 System system{std::move(rules), std::move(chassis)};
70 EXPECT_EQ(system.getChassis().size(), 1);
71 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
Shawn McCarneydb0b8332020-04-06 14:13:04 -050072 EXPECT_NO_THROW(system.getIDMap().getRule("set_voltage_rule"));
73 EXPECT_NO_THROW(system.getIDMap().getDevice("reg1"));
74 EXPECT_NO_THROW(system.getIDMap().getRail("rail1"));
75 EXPECT_THROW(system.getIDMap().getRail("rail2"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -050076 EXPECT_EQ(system.getRules().size(), 1);
77 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
78}
79
Shawn McCarney9bd94d32021-01-25 19:40:42 -060080TEST(SystemTests, ClearCache)
81{
82 // Create PresenceDetection
83 std::vector<std::unique_ptr<Action>> actions{};
84 std::unique_ptr<PresenceDetection> presenceDetection =
85 std::make_unique<PresenceDetection>(std::move(actions));
86 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
87
88 // Create Device that contains PresenceDetection
89 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
90 std::unique_ptr<Device> device = std::make_unique<Device>(
91 "reg1", true,
92 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
93 std::move(i2cInterface), std::move(presenceDetection));
94 Device* devicePtr = device.get();
95
96 // Create Chassis that contains Device
97 std::vector<std::unique_ptr<Device>> devices{};
98 devices.emplace_back(std::move(device));
99 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500100 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600101 Chassis* chassisPtr = chassis.get();
102
103 // Create System that contains Chassis
104 std::vector<std::unique_ptr<Rule>> rules{};
105 std::vector<std::unique_ptr<Chassis>> chassisVec{};
106 chassisVec.emplace_back(std::move(chassis));
107 System system{std::move(rules), std::move(chassisVec)};
108
109 // Cache presence value in PresenceDetection
110 MockServices services{};
111 presenceDetectionPtr->execute(services, system, *chassisPtr, *devicePtr);
112 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
113
114 // Clear cached data in System
115 system.clearCache();
116
117 // Verify presence value no longer cached in PresenceDetection
118 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
119}
120
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500121TEST(SystemTests, CloseDevices)
122{
123 // Specify an empty rules vector
124 std::vector<std::unique_ptr<Rule>> rules{};
125
Bob Kingd692d6d2020-09-14 13:42:57 +0800126 // Create mock services. Expect logDebug() to be called.
127 MockServices services{};
128 MockJournal& journal = services.getMockJournal();
129 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
130 EXPECT_CALL(journal, logDebug("Closing devices in chassis 3")).Times(1);
131 EXPECT_CALL(journal, logInfo(A<const std::string&>())).Times(0);
132 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
133
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500134 // Create Chassis
135 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500136 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
137 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500138
139 // Create System
140 System system{std::move(rules), std::move(chassis)};
141
142 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800143 system.closeDevices(services);
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500144}
145
Shawn McCarney2af52892020-04-14 11:54:45 -0500146TEST(SystemTests, Configure)
147{
Bob King5cfe5102020-07-30 16:26:18 +0800148 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800149 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800150 MockJournal& journal = services.getMockJournal();
151 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
152 EXPECT_CALL(journal, logInfo("Configuring chassis 3")).Times(1);
153 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
154 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800155
Shawn McCarney2af52892020-04-14 11:54:45 -0500156 // Specify an empty rules vector
157 std::vector<std::unique_ptr<Rule>> rules{};
158
159 // Create Chassis
160 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500161 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
162 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney2af52892020-04-14 11:54:45 -0500163
164 // Create System
165 System system{std::move(rules), std::move(chassis)};
166
167 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800168 system.configure(services);
Shawn McCarney2af52892020-04-14 11:54:45 -0500169}
170
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500171TEST(SystemTests, GetChassis)
172{
173 // Specify an empty rules vector
174 std::vector<std::unique_ptr<Rule>> rules{};
175
176 // Create Chassis
177 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500178 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
179 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500180
181 // Create System
182 System system{std::move(rules), std::move(chassis)};
183 EXPECT_EQ(system.getChassis().size(), 2);
184 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
185 EXPECT_EQ(system.getChassis()[1]->getNumber(), 3);
186}
187
188TEST(SystemTests, GetIDMap)
189{
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500190 // Create Rules
191 std::vector<std::unique_ptr<Rule>> rules{};
192 rules.emplace_back(createRule("set_voltage_rule"));
193 rules.emplace_back(createRule("read_sensors_rule"));
194
195 // Create Chassis
196 std::vector<std::unique_ptr<Chassis>> chassis{};
197 {
198 // Chassis 1
199 std::vector<std::unique_ptr<Device>> devices{};
200 devices.emplace_back(createDevice("reg1", {"rail1"}));
201 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500202 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1',
203 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500204 }
205 {
206 // Chassis 2
207 std::vector<std::unique_ptr<Device>> devices{};
208 devices.emplace_back(createDevice("reg3", {"rail3a", "rail3b"}));
209 devices.emplace_back(createDevice("reg4"));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500210 chassis.emplace_back(std::make_unique<Chassis>(2, chassisInvPath + '2',
211 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500212 }
213
214 // Create System
215 System system{std::move(rules), std::move(chassis)};
216 const IDMap& idMap = system.getIDMap();
217
218 // Verify all Rules are in the IDMap
219 EXPECT_NO_THROW(idMap.getRule("set_voltage_rule"));
220 EXPECT_NO_THROW(idMap.getRule("read_sensors_rule"));
221 EXPECT_THROW(idMap.getRule("set_voltage_rule2"), std::invalid_argument);
222
223 // Verify all Devices are in the IDMap
224 EXPECT_NO_THROW(idMap.getDevice("reg1"));
225 EXPECT_NO_THROW(idMap.getDevice("reg2"));
226 EXPECT_NO_THROW(idMap.getDevice("reg3"));
227 EXPECT_NO_THROW(idMap.getDevice("reg4"));
228 EXPECT_THROW(idMap.getDevice("reg5"), std::invalid_argument);
229
230 // Verify all Rails are in the IDMap
231 EXPECT_NO_THROW(idMap.getRail("rail1"));
232 EXPECT_NO_THROW(idMap.getRail("rail2a"));
233 EXPECT_NO_THROW(idMap.getRail("rail2b"));
234 EXPECT_NO_THROW(idMap.getRail("rail3a"));
235 EXPECT_NO_THROW(idMap.getRail("rail3b"));
236 EXPECT_THROW(idMap.getRail("rail4"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500237}
238
239TEST(SystemTests, GetRules)
240{
241 // Create Rules
242 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500243 rules.emplace_back(createRule("set_voltage_rule"));
244 rules.emplace_back(createRule("read_sensors_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500245
246 // Create Chassis
247 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500248 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500249
250 // Create System
251 System system{std::move(rules), std::move(chassis)};
252 EXPECT_EQ(system.getRules().size(), 2);
253 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
254 EXPECT_EQ(system.getRules()[1]->getID(), "read_sensors_rule");
255}
Bob King8e2294d2020-07-14 17:41:31 +0800256
257TEST(SystemTests, MonitorSensors)
258{
Shawn McCarney17bac892021-05-08 07:55:52 -0500259 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800260 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500261 MockSensors& sensors = services.getMockSensors();
262 EXPECT_CALL(sensors, startRail("c1_vdd0",
263 "/xyz/openbmc_project/inventory/system/"
264 "chassis1/motherboard/vdd0_reg",
265 chassisInvPath + '1'))
Bob King8e2294d2020-07-14 17:41:31 +0800266 .Times(1);
Shawn McCarney17bac892021-05-08 07:55:52 -0500267 EXPECT_CALL(sensors, startRail("c2_vdd0",
268 "/xyz/openbmc_project/inventory/system/"
269 "chassis2/motherboard/vdd0_reg",
270 chassisInvPath + '2'))
271 .Times(1);
272 EXPECT_CALL(sensors, setValue).Times(0);
273 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8e2294d2020-07-14 17:41:31 +0800274
Shawn McCarney17bac892021-05-08 07:55:52 -0500275 std::vector<std::unique_ptr<Chassis>> chassisVec{};
Bob King8e2294d2020-07-14 17:41:31 +0800276
Shawn McCarney17bac892021-05-08 07:55:52 -0500277 // Create Chassis 1
278 {
279 // Create SensorMonitoring for Rail
280 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
281 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
282 std::vector<std::unique_ptr<Action>> actions{};
283 actions.emplace_back(std::move(action));
284 std::unique_ptr<SensorMonitoring> sensorMonitoring =
285 std::make_unique<SensorMonitoring>(std::move(actions));
Bob King8e2294d2020-07-14 17:41:31 +0800286
Shawn McCarney17bac892021-05-08 07:55:52 -0500287 // Create Rail
288 std::unique_ptr<Configuration> configuration{};
289 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
290 "c1_vdd0", std::move(configuration), std::move(sensorMonitoring));
Bob King8e2294d2020-07-14 17:41:31 +0800291
Shawn McCarney17bac892021-05-08 07:55:52 -0500292 // Create Device
293 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
294 std::unique_ptr<PresenceDetection> presenceDetection{};
295 std::unique_ptr<Configuration> deviceConfiguration{};
296 std::vector<std::unique_ptr<Rail>> rails{};
297 rails.emplace_back(std::move(rail));
298 std::unique_ptr<Device> device = std::make_unique<Device>(
299 "c1_vdd0_reg", true,
300 "/xyz/openbmc_project/inventory/system/chassis1/motherboard/"
301 "vdd0_reg",
302 std::move(i2cInterface), std::move(presenceDetection),
303 std::move(deviceConfiguration), std::move(rails));
304
305 // Create Chassis
306 std::vector<std::unique_ptr<Device>> devices{};
307 devices.emplace_back(std::move(device));
308 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
309 1, chassisInvPath + '1', std::move(devices));
310 chassisVec.emplace_back(std::move(chassis));
311 }
312
313 // Create Chassis 2
314 {
315 // Create SensorMonitoring for Rail
316 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
317 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
318 std::vector<std::unique_ptr<Action>> actions{};
319 actions.emplace_back(std::move(action));
320 std::unique_ptr<SensorMonitoring> sensorMonitoring =
321 std::make_unique<SensorMonitoring>(std::move(actions));
322
323 // Create Rail
324 std::unique_ptr<Configuration> configuration{};
325 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
326 "c2_vdd0", std::move(configuration), std::move(sensorMonitoring));
327
328 // Create Device
329 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
330 std::unique_ptr<PresenceDetection> presenceDetection{};
331 std::unique_ptr<Configuration> deviceConfiguration{};
332 std::vector<std::unique_ptr<Rail>> rails{};
333 rails.emplace_back(std::move(rail));
334 std::unique_ptr<Device> device = std::make_unique<Device>(
335 "c2_vdd0_reg", true,
336 "/xyz/openbmc_project/inventory/system/chassis2/motherboard/"
337 "vdd0_reg",
338 std::move(i2cInterface), std::move(presenceDetection),
339 std::move(deviceConfiguration), std::move(rails));
340
341 // Create Chassis
342 std::vector<std::unique_ptr<Device>> devices{};
343 devices.emplace_back(std::move(device));
344 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
345 2, chassisInvPath + '2', std::move(devices));
346 chassisVec.emplace_back(std::move(chassis));
347 }
Bob King8e2294d2020-07-14 17:41:31 +0800348
349 // Create System that contains Chassis
350 std::vector<std::unique_ptr<Rule>> rules{};
Bob King8e2294d2020-07-14 17:41:31 +0800351 System system{std::move(rules), std::move(chassisVec)};
352
353 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800354 system.monitorSensors(services);
Bob King8e2294d2020-07-14 17:41:31 +0800355}