blob: 720620d198325de04cefcc495210a2c8171370cc [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 McCarney37af6702021-09-10 00:16:52 -050022#include "log_phase_fault_action.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050023#include "mock_action.hpp"
Shawn McCarney23b0d0d2021-05-14 15:27:59 -050024#include "mock_error_logging.hpp"
Shawn McCarney2af52892020-04-14 11:54:45 -050025#include "mock_journal.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050026#include "mock_sensors.hpp"
Bob King23243f82020-07-29 10:38:57 +080027#include "mock_services.hpp"
Bob King8e2294d2020-07-14 17:41:31 +080028#include "mocked_i2c_interface.hpp"
Shawn McCarney37af6702021-09-10 00:16:52 -050029#include "phase_fault.hpp"
Shawn McCarney32252592021-09-08 15:29:36 -050030#include "phase_fault_detection.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050031#include "presence_detection.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050032#include "rail.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050033#include "rule.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050034#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050035#include "sensors.hpp"
Bob King5cfe5102020-07-30 16:26:18 +080036#include "services.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050037#include "system.hpp"
Shawn McCarney23b0d0d2021-05-14 15:27:59 -050038#include "test_sdbus_error.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050039#include "test_utils.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050040
41#include <memory>
Shawn McCarneydb0b8332020-04-06 14:13:04 -050042#include <stdexcept>
Shawn McCarney2af52892020-04-14 11:54:45 -050043#include <string>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050044#include <utility>
45#include <vector>
46
Bob King8e2294d2020-07-14 17:41:31 +080047#include <gmock/gmock.h>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050048#include <gtest/gtest.h>
49
50using namespace phosphor::power::regulators;
Shawn McCarneydb0b8332020-04-06 14:13:04 -050051using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyc3991f12020-04-05 13:16:06 -050052
Bob King8e2294d2020-07-14 17:41:31 +080053using ::testing::A;
54using ::testing::Return;
Shawn McCarney23b0d0d2021-05-14 15:27:59 -050055using ::testing::Throw;
Bob King8e2294d2020-07-14 17:41:31 +080056using ::testing::TypedEq;
57
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050058static const std::string chassisInvPath{
59 "/xyz/openbmc_project/inventory/system/chassis"};
60
Shawn McCarneyc3991f12020-04-05 13:16:06 -050061TEST(SystemTests, Constructor)
62{
63 // Create Rules
64 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050065 rules.emplace_back(createRule("set_voltage_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050066
67 // Create Chassis
68 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050069 std::vector<std::unique_ptr<Device>> devices{};
70 devices.emplace_back(createDevice("reg1", {"rail1"}));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050071 chassis.emplace_back(
72 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices)));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050073
74 // Create System
75 System system{std::move(rules), std::move(chassis)};
76 EXPECT_EQ(system.getChassis().size(), 1);
77 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
Shawn McCarneydb0b8332020-04-06 14:13:04 -050078 EXPECT_NO_THROW(system.getIDMap().getRule("set_voltage_rule"));
79 EXPECT_NO_THROW(system.getIDMap().getDevice("reg1"));
80 EXPECT_NO_THROW(system.getIDMap().getRail("rail1"));
81 EXPECT_THROW(system.getIDMap().getRail("rail2"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -050082 EXPECT_EQ(system.getRules().size(), 1);
83 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
84}
85
Shawn McCarney9bd94d32021-01-25 19:40:42 -060086TEST(SystemTests, ClearCache)
87{
88 // Create PresenceDetection
89 std::vector<std::unique_ptr<Action>> actions{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -050090 auto presenceDetection =
Shawn McCarney9bd94d32021-01-25 19:40:42 -060091 std::make_unique<PresenceDetection>(std::move(actions));
92 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
93
94 // Create Device that contains PresenceDetection
Shawn McCarneya3fecef2021-09-09 23:15:35 -050095 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
96 auto device = std::make_unique<Device>(
Shawn McCarney9bd94d32021-01-25 19:40:42 -060097 "reg1", true,
98 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
99 std::move(i2cInterface), std::move(presenceDetection));
100 Device* devicePtr = device.get();
101
102 // Create Chassis that contains Device
103 std::vector<std::unique_ptr<Device>> devices{};
104 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500105 auto chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500106 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600107 Chassis* chassisPtr = chassis.get();
108
109 // Create System that contains Chassis
110 std::vector<std::unique_ptr<Rule>> rules{};
111 std::vector<std::unique_ptr<Chassis>> chassisVec{};
112 chassisVec.emplace_back(std::move(chassis));
113 System system{std::move(rules), std::move(chassisVec)};
114
115 // Cache presence value in PresenceDetection
116 MockServices services{};
117 presenceDetectionPtr->execute(services, system, *chassisPtr, *devicePtr);
118 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
119
120 // Clear cached data in System
121 system.clearCache();
122
123 // Verify presence value no longer cached in PresenceDetection
124 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
125}
126
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500127TEST(SystemTests, ClearErrorHistory)
128{
129 // Create SensorMonitoring. Will fail with a DBus exception.
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500130 auto action = std::make_unique<MockAction>();
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500131 EXPECT_CALL(*action, execute)
132 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
133 std::vector<std::unique_ptr<Action>> actions{};
134 actions.emplace_back(std::move(action));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500135 auto sensorMonitoring =
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500136 std::make_unique<SensorMonitoring>(std::move(actions));
137
138 // Create Rail
139 std::unique_ptr<Configuration> configuration{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500140 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration),
141 std::move(sensorMonitoring));
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500142
143 // Create Device that contains Rail
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500144 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500145 std::unique_ptr<PresenceDetection> presenceDetection{};
146 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500147 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500148 std::vector<std::unique_ptr<Rail>> rails{};
149 rails.emplace_back(std::move(rail));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500150 auto device = std::make_unique<Device>(
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500151 "reg1", true,
152 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
153 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500154 std::move(deviceConfiguration), std::move(phaseFaultDetection),
155 std::move(rails));
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500156
157 // Create Chassis that contains Device
158 std::vector<std::unique_ptr<Device>> devices{};
159 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500160 auto chassis =
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500161 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
162
163 // Create System that contains Chassis
164 std::vector<std::unique_ptr<Rule>> rules{};
165 std::vector<std::unique_ptr<Chassis>> chassisVec{};
166 chassisVec.emplace_back(std::move(chassis));
167 System system{std::move(rules), std::move(chassisVec)};
168
169 // Create mock services
170 MockServices services{};
171
172 // Expect Sensors service to be called 5+5=10 times
173 MockSensors& sensors = services.getMockSensors();
174 EXPECT_CALL(sensors, startRail).Times(10);
175 EXPECT_CALL(sensors, setValue).Times(0);
176 EXPECT_CALL(sensors, endRail).Times(10);
177
178 // Expect Journal service to be called 3+3=6 times to log error messages
179 MockJournal& journal = services.getMockJournal();
180 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
181 .Times(6);
182 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
183
184 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
185 MockErrorLogging& errorLogging = services.getMockErrorLogging();
186 EXPECT_CALL(errorLogging, logDBusError).Times(2);
187
188 // Monitor sensors 5 times. Should fail every time, write to journal 3
189 // times, and log one error.
190 for (int i = 1; i <= 5; ++i)
191 {
192 system.monitorSensors(services);
193 }
194
195 // Clear error history
196 system.clearErrorHistory();
197
198 // Monitor sensors 5 times again. Should fail every time, write to journal
199 // 3 times, and log one error.
200 for (int i = 1; i <= 5; ++i)
201 {
202 system.monitorSensors(services);
203 }
204}
205
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500206TEST(SystemTests, CloseDevices)
207{
208 // Specify an empty rules vector
209 std::vector<std::unique_ptr<Rule>> rules{};
210
Bob Kingd692d6d2020-09-14 13:42:57 +0800211 // Create mock services. Expect logDebug() to be called.
212 MockServices services{};
213 MockJournal& journal = services.getMockJournal();
214 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
215 EXPECT_CALL(journal, logDebug("Closing devices in chassis 3")).Times(1);
216 EXPECT_CALL(journal, logInfo(A<const std::string&>())).Times(0);
217 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
218
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500219 // Create Chassis
220 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500221 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
222 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500223
224 // Create System
225 System system{std::move(rules), std::move(chassis)};
226
227 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800228 system.closeDevices(services);
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500229}
230
Shawn McCarney2af52892020-04-14 11:54:45 -0500231TEST(SystemTests, Configure)
232{
Bob King5cfe5102020-07-30 16:26:18 +0800233 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800234 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800235 MockJournal& journal = services.getMockJournal();
236 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
237 EXPECT_CALL(journal, logInfo("Configuring chassis 3")).Times(1);
238 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
239 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800240
Shawn McCarney2af52892020-04-14 11:54:45 -0500241 // Specify an empty rules vector
242 std::vector<std::unique_ptr<Rule>> rules{};
243
244 // Create Chassis
245 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500246 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
247 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney2af52892020-04-14 11:54:45 -0500248
249 // Create System
250 System system{std::move(rules), std::move(chassis)};
251
252 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800253 system.configure(services);
Shawn McCarney2af52892020-04-14 11:54:45 -0500254}
255
Shawn McCarney37af6702021-09-10 00:16:52 -0500256TEST(SystemTests, DetectPhaseFaults)
257{
258 // Create mock services with the following expectations:
259 // - 2 error messages in journal for N phase fault detected in reg0
260 // - 2 error messages in journal for N phase fault detected in reg1
261 // - 1 N phase fault error logged for reg0
262 // - 1 N phase fault error logged for reg1
263 MockServices services{};
264 MockJournal& journal = services.getMockJournal();
265 EXPECT_CALL(journal,
266 logError("n phase fault detected in regulator reg0: count=1"))
267 .Times(1);
268 EXPECT_CALL(journal,
269 logError("n phase fault detected in regulator reg0: count=2"))
270 .Times(1);
271 EXPECT_CALL(journal,
272 logError("n phase fault detected in regulator reg1: count=1"))
273 .Times(1);
274 EXPECT_CALL(journal,
275 logError("n phase fault detected in regulator reg1: count=2"))
276 .Times(1);
277 MockErrorLogging& errorLogging = services.getMockErrorLogging();
278 EXPECT_CALL(errorLogging, logPhaseFault).Times(2);
279
280 std::vector<std::unique_ptr<Chassis>> chassisVec{};
281
282 // Create Chassis 1 with regulator reg0
283 {
284 // Create PhaseFaultDetection
285 auto action = std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
286 std::vector<std::unique_ptr<Action>> actions{};
287 actions.push_back(std::move(action));
288 auto phaseFaultDetection =
289 std::make_unique<PhaseFaultDetection>(std::move(actions));
290
291 // Create Device
292 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
293 std::unique_ptr<PresenceDetection> presenceDetection{};
294 std::unique_ptr<Configuration> configuration{};
295 auto device = std::make_unique<Device>(
296 "reg0", true,
297 "/xyz/openbmc_project/inventory/system/chassis1/motherboard/"
298 "reg0",
299 std::move(i2cInterface), std::move(presenceDetection),
300 std::move(configuration), std::move(phaseFaultDetection));
301
302 // Create Chassis
303 std::vector<std::unique_ptr<Device>> devices{};
304 devices.emplace_back(std::move(device));
305 auto chassis = std::make_unique<Chassis>(1, chassisInvPath + '1',
306 std::move(devices));
307 chassisVec.emplace_back(std::move(chassis));
308 }
309
310 // Create Chassis 2 with regulator reg1
311 {
312 // Create PhaseFaultDetection
313 auto action = std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
314 std::vector<std::unique_ptr<Action>> actions{};
315 actions.push_back(std::move(action));
316 auto phaseFaultDetection =
317 std::make_unique<PhaseFaultDetection>(std::move(actions));
318
319 // Create Device
320 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
321 std::unique_ptr<PresenceDetection> presenceDetection{};
322 std::unique_ptr<Configuration> configuration{};
323 auto device = std::make_unique<Device>(
324 "reg1", true,
325 "/xyz/openbmc_project/inventory/system/chassis2/motherboard/"
326 "reg1",
327 std::move(i2cInterface), std::move(presenceDetection),
328 std::move(configuration), std::move(phaseFaultDetection));
329
330 // Create Chassis
331 std::vector<std::unique_ptr<Device>> devices{};
332 devices.emplace_back(std::move(device));
333 auto chassis = std::make_unique<Chassis>(2, chassisInvPath + '2',
334 std::move(devices));
335 chassisVec.emplace_back(std::move(chassis));
336 }
337
338 // Create System that contains Chassis
339 std::vector<std::unique_ptr<Rule>> rules{};
340 System system{std::move(rules), std::move(chassisVec)};
341
342 // Call detectPhaseFaults() 5 times
343 for (int i = 1; i <= 5; ++i)
344 {
345 system.detectPhaseFaults(services);
346 }
347}
348
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500349TEST(SystemTests, GetChassis)
350{
351 // Specify an empty rules vector
352 std::vector<std::unique_ptr<Rule>> rules{};
353
354 // Create Chassis
355 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500356 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
357 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500358
359 // Create System
360 System system{std::move(rules), std::move(chassis)};
361 EXPECT_EQ(system.getChassis().size(), 2);
362 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
363 EXPECT_EQ(system.getChassis()[1]->getNumber(), 3);
364}
365
366TEST(SystemTests, GetIDMap)
367{
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500368 // Create Rules
369 std::vector<std::unique_ptr<Rule>> rules{};
370 rules.emplace_back(createRule("set_voltage_rule"));
371 rules.emplace_back(createRule("read_sensors_rule"));
372
373 // Create Chassis
374 std::vector<std::unique_ptr<Chassis>> chassis{};
375 {
376 // Chassis 1
377 std::vector<std::unique_ptr<Device>> devices{};
378 devices.emplace_back(createDevice("reg1", {"rail1"}));
379 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500380 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1',
381 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500382 }
383 {
384 // Chassis 2
385 std::vector<std::unique_ptr<Device>> devices{};
386 devices.emplace_back(createDevice("reg3", {"rail3a", "rail3b"}));
387 devices.emplace_back(createDevice("reg4"));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500388 chassis.emplace_back(std::make_unique<Chassis>(2, chassisInvPath + '2',
389 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500390 }
391
392 // Create System
393 System system{std::move(rules), std::move(chassis)};
394 const IDMap& idMap = system.getIDMap();
395
396 // Verify all Rules are in the IDMap
397 EXPECT_NO_THROW(idMap.getRule("set_voltage_rule"));
398 EXPECT_NO_THROW(idMap.getRule("read_sensors_rule"));
399 EXPECT_THROW(idMap.getRule("set_voltage_rule2"), std::invalid_argument);
400
401 // Verify all Devices are in the IDMap
402 EXPECT_NO_THROW(idMap.getDevice("reg1"));
403 EXPECT_NO_THROW(idMap.getDevice("reg2"));
404 EXPECT_NO_THROW(idMap.getDevice("reg3"));
405 EXPECT_NO_THROW(idMap.getDevice("reg4"));
406 EXPECT_THROW(idMap.getDevice("reg5"), std::invalid_argument);
407
408 // Verify all Rails are in the IDMap
409 EXPECT_NO_THROW(idMap.getRail("rail1"));
410 EXPECT_NO_THROW(idMap.getRail("rail2a"));
411 EXPECT_NO_THROW(idMap.getRail("rail2b"));
412 EXPECT_NO_THROW(idMap.getRail("rail3a"));
413 EXPECT_NO_THROW(idMap.getRail("rail3b"));
414 EXPECT_THROW(idMap.getRail("rail4"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500415}
416
417TEST(SystemTests, GetRules)
418{
419 // Create Rules
420 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500421 rules.emplace_back(createRule("set_voltage_rule"));
422 rules.emplace_back(createRule("read_sensors_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500423
424 // Create Chassis
425 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500426 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500427
428 // Create System
429 System system{std::move(rules), std::move(chassis)};
430 EXPECT_EQ(system.getRules().size(), 2);
431 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
432 EXPECT_EQ(system.getRules()[1]->getID(), "read_sensors_rule");
433}
Bob King8e2294d2020-07-14 17:41:31 +0800434
435TEST(SystemTests, MonitorSensors)
436{
Shawn McCarney17bac892021-05-08 07:55:52 -0500437 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800438 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500439 MockSensors& sensors = services.getMockSensors();
440 EXPECT_CALL(sensors, startRail("c1_vdd0",
441 "/xyz/openbmc_project/inventory/system/"
442 "chassis1/motherboard/vdd0_reg",
443 chassisInvPath + '1'))
Bob King8e2294d2020-07-14 17:41:31 +0800444 .Times(1);
Shawn McCarney17bac892021-05-08 07:55:52 -0500445 EXPECT_CALL(sensors, startRail("c2_vdd0",
446 "/xyz/openbmc_project/inventory/system/"
447 "chassis2/motherboard/vdd0_reg",
448 chassisInvPath + '2'))
449 .Times(1);
450 EXPECT_CALL(sensors, setValue).Times(0);
451 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8e2294d2020-07-14 17:41:31 +0800452
Shawn McCarney17bac892021-05-08 07:55:52 -0500453 std::vector<std::unique_ptr<Chassis>> chassisVec{};
Bob King8e2294d2020-07-14 17:41:31 +0800454
Shawn McCarney17bac892021-05-08 07:55:52 -0500455 // Create Chassis 1
456 {
457 // Create SensorMonitoring for Rail
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500458 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500459 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
460 std::vector<std::unique_ptr<Action>> actions{};
461 actions.emplace_back(std::move(action));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500462 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500463 std::make_unique<SensorMonitoring>(std::move(actions));
Bob King8e2294d2020-07-14 17:41:31 +0800464
Shawn McCarney17bac892021-05-08 07:55:52 -0500465 // Create Rail
466 std::unique_ptr<Configuration> configuration{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500467 auto rail = std::make_unique<Rail>("c1_vdd0", std::move(configuration),
468 std::move(sensorMonitoring));
Bob King8e2294d2020-07-14 17:41:31 +0800469
Shawn McCarney17bac892021-05-08 07:55:52 -0500470 // Create Device
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500471 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500472 std::unique_ptr<PresenceDetection> presenceDetection{};
473 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500474 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500475 std::vector<std::unique_ptr<Rail>> rails{};
476 rails.emplace_back(std::move(rail));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500477 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500478 "c1_vdd0_reg", true,
479 "/xyz/openbmc_project/inventory/system/chassis1/motherboard/"
480 "vdd0_reg",
481 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500482 std::move(deviceConfiguration), std::move(phaseFaultDetection),
483 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500484
485 // Create Chassis
486 std::vector<std::unique_ptr<Device>> devices{};
487 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500488 auto chassis = std::make_unique<Chassis>(1, chassisInvPath + '1',
489 std::move(devices));
Shawn McCarney17bac892021-05-08 07:55:52 -0500490 chassisVec.emplace_back(std::move(chassis));
491 }
492
493 // Create Chassis 2
494 {
495 // Create SensorMonitoring for Rail
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500496 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500497 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
498 std::vector<std::unique_ptr<Action>> actions{};
499 actions.emplace_back(std::move(action));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500500 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500501 std::make_unique<SensorMonitoring>(std::move(actions));
502
503 // Create Rail
504 std::unique_ptr<Configuration> configuration{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500505 auto rail = std::make_unique<Rail>("c2_vdd0", std::move(configuration),
506 std::move(sensorMonitoring));
Shawn McCarney17bac892021-05-08 07:55:52 -0500507
508 // Create Device
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500509 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500510 std::unique_ptr<PresenceDetection> presenceDetection{};
511 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500512 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500513 std::vector<std::unique_ptr<Rail>> rails{};
514 rails.emplace_back(std::move(rail));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500515 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500516 "c2_vdd0_reg", true,
517 "/xyz/openbmc_project/inventory/system/chassis2/motherboard/"
518 "vdd0_reg",
519 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500520 std::move(deviceConfiguration), std::move(phaseFaultDetection),
521 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500522
523 // Create Chassis
524 std::vector<std::unique_ptr<Device>> devices{};
525 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500526 auto chassis = std::make_unique<Chassis>(2, chassisInvPath + '2',
527 std::move(devices));
Shawn McCarney17bac892021-05-08 07:55:52 -0500528 chassisVec.emplace_back(std::move(chassis));
529 }
Bob King8e2294d2020-07-14 17:41:31 +0800530
531 // Create System that contains Chassis
532 std::vector<std::unique_ptr<Rule>> rules{};
Bob King8e2294d2020-07-14 17:41:31 +0800533 System system{std::move(rules), std::move(chassisVec)};
534
535 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800536 system.monitorSensors(services);
Bob King8e2294d2020-07-14 17:41:31 +0800537}