blob: 1ea34b3a1d04051d7d135d13b5e95692b1377d62 [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
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500169 // Create lambda that sets MockServices expectations. The lambda allows
170 // us to set expectations multiple times without duplicate code.
171 auto setExpectations = [](MockServices& services) {
172 // Expect Sensors service to be called 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);
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500177
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500178 // Expect Journal service to be called 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);
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500183
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500184 // Expect ErrorLogging service to be called once to log a DBus error
185 MockErrorLogging& errorLogging = services.getMockErrorLogging();
186 EXPECT_CALL(errorLogging, logDBusError).Times(1);
187 };
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500188
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500189 // Monitor sensors 10 times. Verify errors logged.
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500190 {
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500191 // Create mock services. Set expectations via lambda.
192 MockServices services{};
193 setExpectations(services);
194
195 for (int i = 1; i <= 10; ++i)
196 {
197 system.monitorSensors(services);
198 }
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500199 }
200
201 // Clear error history
202 system.clearErrorHistory();
203
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500204 // Monitor sensors 10 more times. Verify errors logged again.
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500205 {
Shawn McCarneyfa2734d2022-03-30 21:16:40 -0500206 // Create mock services. Set expectations via lambda.
207 MockServices services{};
208 setExpectations(services);
209
210 for (int i = 1; i <= 10; ++i)
211 {
212 system.monitorSensors(services);
213 }
Shawn McCarney23b0d0d2021-05-14 15:27:59 -0500214 }
215}
216
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500217TEST(SystemTests, CloseDevices)
218{
219 // Specify an empty rules vector
220 std::vector<std::unique_ptr<Rule>> rules{};
221
Bob Kingd692d6d2020-09-14 13:42:57 +0800222 // Create mock services. Expect logDebug() to be called.
223 MockServices services{};
224 MockJournal& journal = services.getMockJournal();
225 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
226 EXPECT_CALL(journal, logDebug("Closing devices in chassis 3")).Times(1);
227 EXPECT_CALL(journal, logInfo(A<const std::string&>())).Times(0);
228 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
229
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500230 // Create Chassis
231 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500232 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
233 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500234
235 // Create System
236 System system{std::move(rules), std::move(chassis)};
237
238 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800239 system.closeDevices(services);
Shawn McCarney5b19ea52020-06-02 18:52:56 -0500240}
241
Shawn McCarney2af52892020-04-14 11:54:45 -0500242TEST(SystemTests, Configure)
243{
Bob King5cfe5102020-07-30 16:26:18 +0800244 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800245 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800246 MockJournal& journal = services.getMockJournal();
247 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
248 EXPECT_CALL(journal, logInfo("Configuring chassis 3")).Times(1);
249 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
250 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800251
Shawn McCarney2af52892020-04-14 11:54:45 -0500252 // Specify an empty rules vector
253 std::vector<std::unique_ptr<Rule>> rules{};
254
255 // Create Chassis
256 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500257 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
258 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarney2af52892020-04-14 11:54:45 -0500259
260 // Create System
261 System system{std::move(rules), std::move(chassis)};
262
263 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800264 system.configure(services);
Shawn McCarney2af52892020-04-14 11:54:45 -0500265}
266
Shawn McCarney37af6702021-09-10 00:16:52 -0500267TEST(SystemTests, DetectPhaseFaults)
268{
269 // Create mock services with the following expectations:
270 // - 2 error messages in journal for N phase fault detected in reg0
271 // - 2 error messages in journal for N phase fault detected in reg1
272 // - 1 N phase fault error logged for reg0
273 // - 1 N phase fault error logged for reg1
274 MockServices services{};
275 MockJournal& journal = services.getMockJournal();
276 EXPECT_CALL(journal,
277 logError("n phase fault detected in regulator reg0: count=1"))
278 .Times(1);
279 EXPECT_CALL(journal,
280 logError("n phase fault detected in regulator reg0: count=2"))
281 .Times(1);
282 EXPECT_CALL(journal,
283 logError("n phase fault detected in regulator reg1: count=1"))
284 .Times(1);
285 EXPECT_CALL(journal,
286 logError("n phase fault detected in regulator reg1: count=2"))
287 .Times(1);
288 MockErrorLogging& errorLogging = services.getMockErrorLogging();
289 EXPECT_CALL(errorLogging, logPhaseFault).Times(2);
290
291 std::vector<std::unique_ptr<Chassis>> chassisVec{};
292
293 // Create Chassis 1 with regulator reg0
294 {
295 // Create PhaseFaultDetection
296 auto action = std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
297 std::vector<std::unique_ptr<Action>> actions{};
298 actions.push_back(std::move(action));
299 auto phaseFaultDetection =
300 std::make_unique<PhaseFaultDetection>(std::move(actions));
301
302 // Create Device
303 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
304 std::unique_ptr<PresenceDetection> presenceDetection{};
305 std::unique_ptr<Configuration> configuration{};
306 auto device = std::make_unique<Device>(
307 "reg0", true,
308 "/xyz/openbmc_project/inventory/system/chassis1/motherboard/"
309 "reg0",
310 std::move(i2cInterface), std::move(presenceDetection),
311 std::move(configuration), std::move(phaseFaultDetection));
312
313 // Create Chassis
314 std::vector<std::unique_ptr<Device>> devices{};
315 devices.emplace_back(std::move(device));
316 auto chassis = std::make_unique<Chassis>(1, chassisInvPath + '1',
317 std::move(devices));
318 chassisVec.emplace_back(std::move(chassis));
319 }
320
321 // Create Chassis 2 with regulator reg1
322 {
323 // Create PhaseFaultDetection
324 auto action = std::make_unique<LogPhaseFaultAction>(PhaseFaultType::n);
325 std::vector<std::unique_ptr<Action>> actions{};
326 actions.push_back(std::move(action));
327 auto phaseFaultDetection =
328 std::make_unique<PhaseFaultDetection>(std::move(actions));
329
330 // Create Device
331 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
332 std::unique_ptr<PresenceDetection> presenceDetection{};
333 std::unique_ptr<Configuration> configuration{};
334 auto device = std::make_unique<Device>(
335 "reg1", true,
336 "/xyz/openbmc_project/inventory/system/chassis2/motherboard/"
337 "reg1",
338 std::move(i2cInterface), std::move(presenceDetection),
339 std::move(configuration), std::move(phaseFaultDetection));
340
341 // Create Chassis
342 std::vector<std::unique_ptr<Device>> devices{};
343 devices.emplace_back(std::move(device));
344 auto chassis = std::make_unique<Chassis>(2, chassisInvPath + '2',
345 std::move(devices));
346 chassisVec.emplace_back(std::move(chassis));
347 }
348
349 // Create System that contains Chassis
350 std::vector<std::unique_ptr<Rule>> rules{};
351 System system{std::move(rules), std::move(chassisVec)};
352
353 // Call detectPhaseFaults() 5 times
354 for (int i = 1; i <= 5; ++i)
355 {
356 system.detectPhaseFaults(services);
357 }
358}
359
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500360TEST(SystemTests, GetChassis)
361{
362 // Specify an empty rules vector
363 std::vector<std::unique_ptr<Rule>> rules{};
364
365 // Create Chassis
366 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500367 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1'));
368 chassis.emplace_back(std::make_unique<Chassis>(3, chassisInvPath + '3'));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500369
370 // Create System
371 System system{std::move(rules), std::move(chassis)};
372 EXPECT_EQ(system.getChassis().size(), 2);
373 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
374 EXPECT_EQ(system.getChassis()[1]->getNumber(), 3);
375}
376
377TEST(SystemTests, GetIDMap)
378{
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500379 // Create Rules
380 std::vector<std::unique_ptr<Rule>> rules{};
381 rules.emplace_back(createRule("set_voltage_rule"));
382 rules.emplace_back(createRule("read_sensors_rule"));
383
384 // Create Chassis
385 std::vector<std::unique_ptr<Chassis>> chassis{};
386 {
387 // Chassis 1
388 std::vector<std::unique_ptr<Device>> devices{};
389 devices.emplace_back(createDevice("reg1", {"rail1"}));
390 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500391 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath + '1',
392 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500393 }
394 {
395 // Chassis 2
396 std::vector<std::unique_ptr<Device>> devices{};
397 devices.emplace_back(createDevice("reg3", {"rail3a", "rail3b"}));
398 devices.emplace_back(createDevice("reg4"));
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500399 chassis.emplace_back(std::make_unique<Chassis>(2, chassisInvPath + '2',
400 std::move(devices)));
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500401 }
402
403 // Create System
404 System system{std::move(rules), std::move(chassis)};
405 const IDMap& idMap = system.getIDMap();
406
407 // Verify all Rules are in the IDMap
408 EXPECT_NO_THROW(idMap.getRule("set_voltage_rule"));
409 EXPECT_NO_THROW(idMap.getRule("read_sensors_rule"));
410 EXPECT_THROW(idMap.getRule("set_voltage_rule2"), std::invalid_argument);
411
412 // Verify all Devices are in the IDMap
413 EXPECT_NO_THROW(idMap.getDevice("reg1"));
414 EXPECT_NO_THROW(idMap.getDevice("reg2"));
415 EXPECT_NO_THROW(idMap.getDevice("reg3"));
416 EXPECT_NO_THROW(idMap.getDevice("reg4"));
417 EXPECT_THROW(idMap.getDevice("reg5"), std::invalid_argument);
418
419 // Verify all Rails are in the IDMap
420 EXPECT_NO_THROW(idMap.getRail("rail1"));
421 EXPECT_NO_THROW(idMap.getRail("rail2a"));
422 EXPECT_NO_THROW(idMap.getRail("rail2b"));
423 EXPECT_NO_THROW(idMap.getRail("rail3a"));
424 EXPECT_NO_THROW(idMap.getRail("rail3b"));
425 EXPECT_THROW(idMap.getRail("rail4"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500426}
427
428TEST(SystemTests, GetRules)
429{
430 // Create Rules
431 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500432 rules.emplace_back(createRule("set_voltage_rule"));
433 rules.emplace_back(createRule("read_sensors_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500434
435 // Create Chassis
436 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500437 chassis.emplace_back(std::make_unique<Chassis>(1, chassisInvPath));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500438
439 // Create System
440 System system{std::move(rules), std::move(chassis)};
441 EXPECT_EQ(system.getRules().size(), 2);
442 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
443 EXPECT_EQ(system.getRules()[1]->getID(), "read_sensors_rule");
444}
Bob King8e2294d2020-07-14 17:41:31 +0800445
446TEST(SystemTests, MonitorSensors)
447{
Shawn McCarney17bac892021-05-08 07:55:52 -0500448 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800449 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500450 MockSensors& sensors = services.getMockSensors();
451 EXPECT_CALL(sensors, startRail("c1_vdd0",
452 "/xyz/openbmc_project/inventory/system/"
453 "chassis1/motherboard/vdd0_reg",
454 chassisInvPath + '1'))
Bob King8e2294d2020-07-14 17:41:31 +0800455 .Times(1);
Shawn McCarney17bac892021-05-08 07:55:52 -0500456 EXPECT_CALL(sensors, startRail("c2_vdd0",
457 "/xyz/openbmc_project/inventory/system/"
458 "chassis2/motherboard/vdd0_reg",
459 chassisInvPath + '2'))
460 .Times(1);
461 EXPECT_CALL(sensors, setValue).Times(0);
462 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8e2294d2020-07-14 17:41:31 +0800463
Shawn McCarney17bac892021-05-08 07:55:52 -0500464 std::vector<std::unique_ptr<Chassis>> chassisVec{};
Bob King8e2294d2020-07-14 17:41:31 +0800465
Shawn McCarney17bac892021-05-08 07:55:52 -0500466 // Create Chassis 1
467 {
468 // Create SensorMonitoring for Rail
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500469 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500470 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
471 std::vector<std::unique_ptr<Action>> actions{};
472 actions.emplace_back(std::move(action));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500473 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500474 std::make_unique<SensorMonitoring>(std::move(actions));
Bob King8e2294d2020-07-14 17:41:31 +0800475
Shawn McCarney17bac892021-05-08 07:55:52 -0500476 // Create Rail
477 std::unique_ptr<Configuration> configuration{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500478 auto rail = std::make_unique<Rail>("c1_vdd0", std::move(configuration),
479 std::move(sensorMonitoring));
Bob King8e2294d2020-07-14 17:41:31 +0800480
Shawn McCarney17bac892021-05-08 07:55:52 -0500481 // Create Device
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500482 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500483 std::unique_ptr<PresenceDetection> presenceDetection{};
484 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500485 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500486 std::vector<std::unique_ptr<Rail>> rails{};
487 rails.emplace_back(std::move(rail));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500488 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500489 "c1_vdd0_reg", true,
490 "/xyz/openbmc_project/inventory/system/chassis1/motherboard/"
491 "vdd0_reg",
492 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500493 std::move(deviceConfiguration), std::move(phaseFaultDetection),
494 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500495
496 // Create Chassis
497 std::vector<std::unique_ptr<Device>> devices{};
498 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500499 auto chassis = std::make_unique<Chassis>(1, chassisInvPath + '1',
500 std::move(devices));
Shawn McCarney17bac892021-05-08 07:55:52 -0500501 chassisVec.emplace_back(std::move(chassis));
502 }
503
504 // Create Chassis 2
505 {
506 // Create SensorMonitoring for Rail
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500507 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500508 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
509 std::vector<std::unique_ptr<Action>> actions{};
510 actions.emplace_back(std::move(action));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500511 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500512 std::make_unique<SensorMonitoring>(std::move(actions));
513
514 // Create Rail
515 std::unique_ptr<Configuration> configuration{};
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500516 auto rail = std::make_unique<Rail>("c2_vdd0", std::move(configuration),
517 std::move(sensorMonitoring));
Shawn McCarney17bac892021-05-08 07:55:52 -0500518
519 // Create Device
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500520 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500521 std::unique_ptr<PresenceDetection> presenceDetection{};
522 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500523 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500524 std::vector<std::unique_ptr<Rail>> rails{};
525 rails.emplace_back(std::move(rail));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500526 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500527 "c2_vdd0_reg", true,
528 "/xyz/openbmc_project/inventory/system/chassis2/motherboard/"
529 "vdd0_reg",
530 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500531 std::move(deviceConfiguration), std::move(phaseFaultDetection),
532 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500533
534 // Create Chassis
535 std::vector<std::unique_ptr<Device>> devices{};
536 devices.emplace_back(std::move(device));
Shawn McCarneya3fecef2021-09-09 23:15:35 -0500537 auto chassis = std::make_unique<Chassis>(2, chassisInvPath + '2',
538 std::move(devices));
Shawn McCarney17bac892021-05-08 07:55:52 -0500539 chassisVec.emplace_back(std::move(chassis));
540 }
Bob King8e2294d2020-07-14 17:41:31 +0800541
542 // Create System that contains Chassis
543 std::vector<std::unique_ptr<Rule>> rules{};
Bob King8e2294d2020-07-14 17:41:31 +0800544 System system{std::move(rules), std::move(chassisVec)};
545
546 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800547 system.monitorSensors(services);
Bob King8e2294d2020-07-14 17:41:31 +0800548}