blob: bda036f3831b26b00c9c73f837e9fc14e7f6bb42 [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 McCarney0b1a0e72020-03-11 18:01:44 -050016#include "action.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050017#include "chassis.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050018#include "configuration.hpp"
Shawn McCarneya2461b32019-10-24 18:53:01 -050019#include "device.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060020#include "i2c_interface.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050021#include "id_map.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050022#include "mock_action.hpp"
Shawn McCarney81a2f902021-03-23 21:41:34 -050023#include "mock_error_logging.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050024#include "mock_journal.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050025#include "mock_sensors.hpp"
Bob King23243f82020-07-29 10:38:57 +080026#include "mock_services.hpp"
Shawn McCarneyb4d18a42020-06-02 10:27:05 -050027#include "mocked_i2c_interface.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050028#include "presence_detection.hpp"
29#include "rail.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050030#include "rule.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050031#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050032#include "sensors.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050033#include "system.hpp"
Shawn McCarney371e2442021-05-14 14:18:07 -050034#include "test_sdbus_error.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050035#include "test_utils.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060036
37#include <memory>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050038#include <optional>
Shawn McCarney525e20c2020-04-14 11:05:39 -050039#include <string>
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060040#include <utility>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050041#include <vector>
Shawn McCarneya2461b32019-10-24 18:53:01 -050042
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050043#include <gmock/gmock.h>
Shawn McCarneya2461b32019-10-24 18:53:01 -050044#include <gtest/gtest.h>
45
46using namespace phosphor::power::regulators;
Shawn McCarney8a3afd72020-03-12 14:28:44 -050047using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060048
Bob King8e1cd0b2020-07-08 13:30:27 +080049using ::testing::A;
Shawn McCarney81a2f902021-03-23 21:41:34 -050050using ::testing::Ref;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050051using ::testing::Return;
Shawn McCarneyb4d18a42020-06-02 10:27:05 -050052using ::testing::Throw;
Bob King8e1cd0b2020-07-08 13:30:27 +080053using ::testing::TypedEq;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050054
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050055static const std::string chassisInvPath{
56 "/xyz/openbmc_project/inventory/system/chassis"};
57
Shawn McCarneya2461b32019-10-24 18:53:01 -050058TEST(DeviceTests, Constructor)
59{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050060 // Test where only required parameters are specified
61 {
62 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
63 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
Bob Kinga76898f2020-10-13 15:08:33 +080064 Device device{
65 "vdd_reg", true,
66 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
67 std::move(i2cInterface)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050068 EXPECT_EQ(device.getID(), "vdd_reg");
69 EXPECT_EQ(device.isRegulator(), true);
Bob Kinga76898f2020-10-13 15:08:33 +080070 EXPECT_EQ(
71 device.getFRU(),
72 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2");
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050073 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
74 EXPECT_EQ(device.getPresenceDetection(), nullptr);
75 EXPECT_EQ(device.getConfiguration(), nullptr);
76 EXPECT_EQ(device.getRails().size(), 0);
77 }
78
79 // Test where all parameters are specified
80 {
81 // Create I2CInterface
82 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
83 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
84
85 // Create PresenceDetection
86 std::vector<std::unique_ptr<Action>> actions{};
87 actions.push_back(std::make_unique<MockAction>());
88 std::unique_ptr<PresenceDetection> presenceDetection =
89 std::make_unique<PresenceDetection>(std::move(actions));
90
91 // Create Configuration
92 std::optional<double> volts{};
93 actions.clear();
94 actions.push_back(std::make_unique<MockAction>());
95 actions.push_back(std::make_unique<MockAction>());
96 std::unique_ptr<Configuration> configuration =
97 std::make_unique<Configuration>(volts, std::move(actions));
98
99 // Create vector of Rail objects
100 std::vector<std::unique_ptr<Rail>> rails{};
101 rails.push_back(std::make_unique<Rail>("vdd0"));
102 rails.push_back(std::make_unique<Rail>("vdd1"));
103
104 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800105 Device device{
106 "vdd_reg",
107 false,
108 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
109 std::move(i2cInterface),
110 std::move(presenceDetection),
111 std::move(configuration),
112 std::move(rails)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500113 EXPECT_EQ(device.getID(), "vdd_reg");
114 EXPECT_EQ(device.isRegulator(), false);
Bob Kinga76898f2020-10-13 15:08:33 +0800115 EXPECT_EQ(
116 device.getFRU(),
117 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1");
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500118 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
119 EXPECT_NE(device.getPresenceDetection(), nullptr);
120 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
121 EXPECT_NE(device.getConfiguration(), nullptr);
122 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), false);
123 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
124 EXPECT_EQ(device.getRails().size(), 2);
125 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500126}
127
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500128TEST(DeviceTests, AddToIDMap)
129{
130 std::unique_ptr<PresenceDetection> presenceDetection{};
131 std::unique_ptr<Configuration> configuration{};
132
133 // Create vector of Rail objects
134 std::vector<std::unique_ptr<Rail>> rails{};
135 rails.push_back(std::make_unique<Rail>("vdd0"));
136 rails.push_back(std::make_unique<Rail>("vdd1"));
137
138 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800139 Device device{
140 "vdd_reg",
141 false,
142 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
143 std::move(createI2CInterface()),
144 std::move(presenceDetection),
145 std::move(configuration),
146 std::move(rails)};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500147
148 // Add Device and Rail objects to an IDMap
149 IDMap idMap{};
150 device.addToIDMap(idMap);
151
152 // Verify Device is in the IDMap
153 EXPECT_NO_THROW(idMap.getDevice("vdd_reg"));
154 EXPECT_THROW(idMap.getDevice("vio_reg"), std::invalid_argument);
155
156 // Verify all Rails are in the IDMap
157 EXPECT_NO_THROW(idMap.getRail("vdd0"));
158 EXPECT_NO_THROW(idMap.getRail("vdd1"));
159 EXPECT_THROW(idMap.getRail("vdd2"), std::invalid_argument);
160}
161
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600162TEST(DeviceTests, ClearCache)
163{
164 // Test where Device does not contain a PresenceDetection object
165 try
166 {
167 Device device{
168 "vdd_reg", false,
169 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
170 std::move(createI2CInterface())};
171 device.clearCache();
172 }
173 catch (...)
174 {
175 ADD_FAILURE() << "Should not have caught exception.";
176 }
177
178 // Test where Device contains a PresenceDetection object
179 {
180 // Create PresenceDetection
181 std::vector<std::unique_ptr<Action>> actions{};
182 std::unique_ptr<PresenceDetection> presenceDetection =
183 std::make_unique<PresenceDetection>(std::move(actions));
184 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
185
186 // Create Device
187 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
188 std::unique_ptr<Device> device = std::make_unique<Device>(
189 "reg1", true,
190 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
191 std::move(i2cInterface), std::move(presenceDetection));
192 Device* devicePtr = device.get();
193
194 // Create Chassis that contains Device
195 std::vector<std::unique_ptr<Device>> devices{};
196 devices.emplace_back(std::move(device));
197 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500198 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600199 Chassis* chassisPtr = chassis.get();
200
201 // Create System that contains Chassis
202 std::vector<std::unique_ptr<Rule>> rules{};
203 std::vector<std::unique_ptr<Chassis>> chassisVec{};
204 chassisVec.emplace_back(std::move(chassis));
205 System system{std::move(rules), std::move(chassisVec)};
206
207 // Cache presence value in PresenceDetection
208 MockServices services{};
209 presenceDetectionPtr->execute(services, system, *chassisPtr,
210 *devicePtr);
211 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
212
213 // Clear cached data in Device
214 devicePtr->clearCache();
215
216 // Verify presence value no longer cached in PresenceDetection
217 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
218 }
219}
220
Shawn McCarney371e2442021-05-14 14:18:07 -0500221TEST(DeviceTests, ClearErrorHistory)
222{
223 // Create SensorMonitoring. Will fail with a DBus exception.
224 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
225 EXPECT_CALL(*action, execute)
226 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
227 std::vector<std::unique_ptr<Action>> actions{};
228 actions.emplace_back(std::move(action));
229 std::unique_ptr<SensorMonitoring> sensorMonitoring =
230 std::make_unique<SensorMonitoring>(std::move(actions));
231
232 // Create Rail
233 std::unique_ptr<Configuration> configuration{};
234 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
235 "vddr1", std::move(configuration), std::move(sensorMonitoring));
236
237 // Create Device that contains Rail
238 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
239 std::make_unique<i2c::MockedI2CInterface>();
240 std::unique_ptr<PresenceDetection> presenceDetection{};
241 std::unique_ptr<Configuration> deviceConfiguration{};
242 std::vector<std::unique_ptr<Rail>> rails{};
243 rails.emplace_back(std::move(rail));
244 std::unique_ptr<Device> device = std::make_unique<Device>(
245 "reg1", true,
246 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
247 std::move(i2cInterface), std::move(presenceDetection),
248 std::move(deviceConfiguration), std::move(rails));
249 Device* devicePtr = device.get();
250
251 // Create Chassis that contains Device
252 std::vector<std::unique_ptr<Device>> devices{};
253 devices.emplace_back(std::move(device));
254 std::unique_ptr<Chassis> chassis =
255 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
256 Chassis* chassisPtr = chassis.get();
257
258 // Create System that contains Chassis
259 std::vector<std::unique_ptr<Rule>> rules{};
260 std::vector<std::unique_ptr<Chassis>> chassisVec{};
261 chassisVec.emplace_back(std::move(chassis));
262 System system{std::move(rules), std::move(chassisVec)};
263
264 // Create mock services
265 MockServices services{};
266
267 // Expect Sensors service to be called 5+5=10 times
268 MockSensors& sensors = services.getMockSensors();
269 EXPECT_CALL(sensors, startRail).Times(10);
270 EXPECT_CALL(sensors, setValue).Times(0);
271 EXPECT_CALL(sensors, endRail).Times(10);
272
273 // Expect Journal service to be called 3+3=6 times to log error messages
274 MockJournal& journal = services.getMockJournal();
275 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
276 .Times(6);
277 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
278
279 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
280 MockErrorLogging& errorLogging = services.getMockErrorLogging();
281 EXPECT_CALL(errorLogging, logDBusError).Times(2);
282
283 // Monitor sensors 5 times. Should fail every time, write to journal 3
284 // times, and log one error.
285 for (int i = 1; i <= 5; ++i)
286 {
287 devicePtr->monitorSensors(services, system, *chassisPtr);
288 }
289
290 // Clear error history
291 devicePtr->clearErrorHistory();
292
293 // Monitor sensors 5 times again. Should fail every time, write to journal
294 // 3 times, and log one error.
295 for (int i = 1; i <= 5; ++i)
296 {
297 devicePtr->monitorSensors(services, system, *chassisPtr);
298 }
299}
300
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500301TEST(DeviceTests, Close)
302{
303 // Test where works: I2C interface is not open
304 {
305 // Create mock I2CInterface
306 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
307 std::make_unique<i2c::MockedI2CInterface>();
308 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false));
309 EXPECT_CALL(*i2cInterface, close).Times(0);
310
Bob Kingd692d6d2020-09-14 13:42:57 +0800311 // Create mock services. No logError should occur.
312 MockServices services{};
313 MockJournal& journal = services.getMockJournal();
314 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
315 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
316 .Times(0);
317
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500318 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800319 Device device{
320 "vdd_reg", true,
321 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
322 std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500323
324 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800325 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500326 }
327
328 // Test where works: I2C interface is open
329 {
330 // Create mock I2CInterface
331 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
332 std::make_unique<i2c::MockedI2CInterface>();
333 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
334 EXPECT_CALL(*i2cInterface, close).Times(1);
335
Bob Kingd692d6d2020-09-14 13:42:57 +0800336 // Create mock services. No logError should occur.
337 MockServices services{};
338 MockJournal& journal = services.getMockJournal();
339 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
340 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
341 .Times(0);
342
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500343 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800344 Device device{
345 "vdd_reg", true,
346 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
347 std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500348
349 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800350 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500351 }
352
353 // Test where fails: closing I2C interface fails
354 {
355 // Create mock I2CInterface
356 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
357 std::make_unique<i2c::MockedI2CInterface>();
358 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
359 EXPECT_CALL(*i2cInterface, close)
360 .Times(1)
361 .WillOnce(Throw(
362 i2c::I2CException{"Failed to close", "/dev/i2c-1", 0x70}));
363
Shawn McCarney81a2f902021-03-23 21:41:34 -0500364 // Create mock services. Expect logError() and logI2CError() to be
365 // called.
Bob Kingd692d6d2020-09-14 13:42:57 +0800366 MockServices services{};
Shawn McCarney81a2f902021-03-23 21:41:34 -0500367 MockErrorLogging& errorLogging = services.getMockErrorLogging();
Bob Kingd692d6d2020-09-14 13:42:57 +0800368 MockJournal& journal = services.getMockJournal();
369 std::vector<std::string> expectedErrMessagesException{
370 "I2CException: Failed to close: bus /dev/i2c-1, addr 0x70"};
371 EXPECT_CALL(journal, logError("Unable to close device vdd_reg"))
372 .Times(1);
373 EXPECT_CALL(journal, logError(expectedErrMessagesException)).Times(1);
Shawn McCarney81a2f902021-03-23 21:41:34 -0500374 EXPECT_CALL(errorLogging,
375 logI2CError(Entry::Level::Notice, Ref(journal),
376 "/dev/i2c-1", 0x70, 0))
377 .Times(1);
Bob Kingd692d6d2020-09-14 13:42:57 +0800378
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500379 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800380 Device device{
381 "vdd_reg", true,
382 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
383 std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500384
385 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800386 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500387 }
388}
389
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500390TEST(DeviceTests, Configure)
391{
Shawn McCarney48033bf2021-01-27 17:56:49 -0600392 // Test where device is not present
393 {
394 // Create mock services. No logging should occur.
395 MockServices services{};
396 MockJournal& journal = services.getMockJournal();
397 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
398 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
399
400 // Create PresenceDetection. Indicates device is not present.
401 std::unique_ptr<MockAction> presAction = std::make_unique<MockAction>();
402 EXPECT_CALL(*presAction, execute).Times(1).WillOnce(Return(false));
403 std::vector<std::unique_ptr<Action>> presActions{};
404 presActions.emplace_back(std::move(presAction));
405 std::unique_ptr<PresenceDetection> presenceDetection =
406 std::make_unique<PresenceDetection>(std::move(presActions));
407
408 // Create Configuration. Action inside it should not be executed.
409 std::optional<double> volts{};
410 std::unique_ptr<MockAction> confAction = std::make_unique<MockAction>();
411 EXPECT_CALL(*confAction, execute).Times(0);
412 std::vector<std::unique_ptr<Action>> confActions{};
413 confActions.emplace_back(std::move(confAction));
414 std::unique_ptr<Configuration> configuration =
415 std::make_unique<Configuration>(volts, std::move(confActions));
416
417 // Create Device
418 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
419 std::unique_ptr<Device> device = std::make_unique<Device>(
420 "reg1", true,
421 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
422 std::move(i2cInterface), std::move(presenceDetection),
423 std::move(configuration));
424 Device* devicePtr = device.get();
425
426 // Create Chassis that contains Device
427 std::vector<std::unique_ptr<Device>> devices{};
428 devices.emplace_back(std::move(device));
429 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500430 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600431 Chassis* chassisPtr = chassis.get();
432
433 // Create System that contains Chassis
434 std::vector<std::unique_ptr<Rule>> rules{};
435 std::vector<std::unique_ptr<Chassis>> chassisVec{};
436 chassisVec.emplace_back(std::move(chassis));
437 System system{std::move(rules), std::move(chassisVec)};
438
439 // Call configure(). Should do nothing.
440 devicePtr->configure(services, system, *chassisPtr);
441 }
442
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500443 // Test where Configuration and Rails were not specified in constructor
444 {
Bob King5cfe5102020-07-30 16:26:18 +0800445 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +0800446 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800447 MockJournal& journal = services.getMockJournal();
448 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
449 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800450
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500451 // Create Device
452 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
453 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800454 "reg1", true,
455 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500456 std::move(i2cInterface));
457 Device* devicePtr = device.get();
458
459 // Create Chassis that contains Device
460 std::vector<std::unique_ptr<Device>> devices{};
461 devices.emplace_back(std::move(device));
462 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500463 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500464 Chassis* chassisPtr = chassis.get();
465
466 // Create System that contains Chassis
467 std::vector<std::unique_ptr<Rule>> rules{};
468 std::vector<std::unique_ptr<Chassis>> chassisVec{};
469 chassisVec.emplace_back(std::move(chassis));
470 System system{std::move(rules), std::move(chassisVec)};
471
Bob King5cfe5102020-07-30 16:26:18 +0800472 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800473 devicePtr->configure(services, system, *chassisPtr);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500474 }
475
476 // Test where Configuration and Rails were specified in constructor
477 {
478 std::vector<std::unique_ptr<Rail>> rails{};
479
Bob King5cfe5102020-07-30 16:26:18 +0800480 // Create mock services. Expect logDebug() to be called.
481 // For the Device and both Rails, should execute the Configuration
482 // and log a debug message.
483 MockServices services{};
484 MockJournal& journal = services.getMockJournal();
485 EXPECT_CALL(journal, logDebug("Configuring reg1")).Times(1);
486 EXPECT_CALL(journal, logDebug("Configuring vdd0: volts=1.300000"))
487 .Times(1);
488 EXPECT_CALL(journal, logDebug("Configuring vio0: volts=3.200000"))
489 .Times(1);
490 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
491
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500492 // Create Rail vdd0
493 {
494 // Create Configuration for Rail
495 std::optional<double> volts{1.3};
496 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
497 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
498 std::vector<std::unique_ptr<Action>> actions{};
499 actions.emplace_back(std::move(action));
500 std::unique_ptr<Configuration> configuration =
501 std::make_unique<Configuration>(volts, std::move(actions));
502
503 // Create Rail
504 std::unique_ptr<Rail> rail =
505 std::make_unique<Rail>("vdd0", std::move(configuration));
506 rails.emplace_back(std::move(rail));
507 }
508
509 // Create Rail vio0
510 {
511 // Create Configuration for Rail
512 std::optional<double> volts{3.2};
513 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
514 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
515 std::vector<std::unique_ptr<Action>> actions{};
516 actions.emplace_back(std::move(action));
517 std::unique_ptr<Configuration> configuration =
518 std::make_unique<Configuration>(volts, std::move(actions));
519
520 // Create Rail
521 std::unique_ptr<Rail> rail =
522 std::make_unique<Rail>("vio0", std::move(configuration));
523 rails.emplace_back(std::move(rail));
524 }
525
526 // Create Configuration for Device
527 std::optional<double> volts{};
528 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
529 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
530 std::vector<std::unique_ptr<Action>> actions{};
531 actions.emplace_back(std::move(action));
532 std::unique_ptr<Configuration> configuration =
533 std::make_unique<Configuration>(volts, std::move(actions));
534
535 // Create Device
536 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
537 std::unique_ptr<PresenceDetection> presenceDetection{};
538 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800539 "reg1", true,
540 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500541 std::move(i2cInterface), std::move(presenceDetection),
542 std::move(configuration), std::move(rails));
543 Device* devicePtr = device.get();
544
545 // Create Chassis that contains Device
546 std::vector<std::unique_ptr<Device>> devices{};
547 devices.emplace_back(std::move(device));
548 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500549 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500550 Chassis* chassisPtr = chassis.get();
551
552 // Create System that contains Chassis
553 std::vector<std::unique_ptr<Rule>> rules{};
554 std::vector<std::unique_ptr<Chassis>> chassisVec{};
555 chassisVec.emplace_back(std::move(chassis));
556 System system{std::move(rules), std::move(chassisVec)};
557
Bob King5cfe5102020-07-30 16:26:18 +0800558 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800559 devicePtr->configure(services, system, *chassisPtr);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500560 }
561}
562
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500563TEST(DeviceTests, GetConfiguration)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500564{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500565 // Test where Configuration was not specified in constructor
566 {
Bob Kinga76898f2020-10-13 15:08:33 +0800567 Device device{
568 "vdd_reg", true,
569 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
570 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500571 EXPECT_EQ(device.getConfiguration(), nullptr);
572 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600573
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500574 // Test where Configuration was specified in constructor
575 {
576 std::unique_ptr<PresenceDetection> presenceDetection{};
577
578 // Create Configuration
579 std::optional<double> volts{3.2};
580 std::vector<std::unique_ptr<Action>> actions{};
581 actions.push_back(std::make_unique<MockAction>());
582 actions.push_back(std::make_unique<MockAction>());
583 std::unique_ptr<Configuration> configuration =
584 std::make_unique<Configuration>(volts, std::move(actions));
585
586 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800587 Device device{
588 "vdd_reg",
589 true,
590 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
591 std::move(createI2CInterface()),
592 std::move(presenceDetection),
593 std::move(configuration)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500594 EXPECT_NE(device.getConfiguration(), nullptr);
595 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true);
596 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2);
597 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
598 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600599}
600
601TEST(DeviceTests, GetFRU)
602{
Bob Kinga76898f2020-10-13 15:08:33 +0800603 Device device{
604 "vdd_reg", true,
605 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
606 std::move(createI2CInterface())};
607 EXPECT_EQ(device.getFRU(),
608 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2");
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600609}
610
611TEST(DeviceTests, GetI2CInterface)
612{
613 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
614 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
Bob Kinga76898f2020-10-13 15:08:33 +0800615 Device device{
616 "vdd_reg", true,
617 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
618 std::move(i2cInterface)};
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600619 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
Shawn McCarneya2461b32019-10-24 18:53:01 -0500620}
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500621
622TEST(DeviceTests, GetID)
623{
Bob Kinga76898f2020-10-13 15:08:33 +0800624 Device device{
625 "vdd_reg", false,
626 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
627 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500628 EXPECT_EQ(device.getID(), "vdd_reg");
629}
630
631TEST(DeviceTests, GetPresenceDetection)
632{
633 // Test where PresenceDetection was not specified in constructor
634 {
Bob Kinga76898f2020-10-13 15:08:33 +0800635 Device device{
636 "vdd_reg", true,
637 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
638 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500639 EXPECT_EQ(device.getPresenceDetection(), nullptr);
640 }
641
642 // Test where PresenceDetection was specified in constructor
643 {
644 // Create PresenceDetection
645 std::vector<std::unique_ptr<Action>> actions{};
646 actions.push_back(std::make_unique<MockAction>());
647 std::unique_ptr<PresenceDetection> presenceDetection =
648 std::make_unique<PresenceDetection>(std::move(actions));
649
650 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800651 Device device{
652 "vdd_reg", false,
653 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
654 std::move(createI2CInterface()), std::move(presenceDetection)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500655 EXPECT_NE(device.getPresenceDetection(), nullptr);
656 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
657 }
658}
659
660TEST(DeviceTests, GetRails)
661{
662 // Test where no rails were specified in constructor
663 {
Bob Kinga76898f2020-10-13 15:08:33 +0800664 Device device{
665 "vdd_reg", true,
666 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
667 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500668 EXPECT_EQ(device.getRails().size(), 0);
669 }
670
671 // Test where rails were specified in constructor
672 {
673 std::unique_ptr<PresenceDetection> presenceDetection{};
674 std::unique_ptr<Configuration> configuration{};
675
676 // Create vector of Rail objects
677 std::vector<std::unique_ptr<Rail>> rails{};
678 rails.push_back(std::make_unique<Rail>("vdd0"));
679 rails.push_back(std::make_unique<Rail>("vdd1"));
680
681 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800682 Device device{
683 "vdd_reg",
684 false,
685 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
686 std::move(createI2CInterface()),
687 std::move(presenceDetection),
688 std::move(configuration),
689 std::move(rails)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500690 EXPECT_EQ(device.getRails().size(), 2);
691 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0");
692 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1");
693 }
694}
695
Shawn McCarney48033bf2021-01-27 17:56:49 -0600696TEST(DeviceTests, IsPresent)
697{
698 // Test where PresenceDetection not specified in constructor
699 {
700 // Create Device
701 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
702 std::unique_ptr<Device> device = std::make_unique<Device>(
703 "reg1", true,
704 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
705 std::move(i2cInterface));
706 Device* devicePtr = device.get();
707
708 // Create Chassis that contains Device
709 std::vector<std::unique_ptr<Device>> devices{};
710 devices.emplace_back(std::move(device));
711 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500712 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600713 Chassis* chassisPtr = chassis.get();
714
715 // Create System that contains Chassis
716 std::vector<std::unique_ptr<Rule>> rules{};
717 std::vector<std::unique_ptr<Chassis>> chassisVec{};
718 chassisVec.emplace_back(std::move(chassis));
719 System system{std::move(rules), std::move(chassisVec)};
720
721 // Create MockServices
722 MockServices services{};
723
724 // Since no PresenceDetection defined, isPresent() should return true
725 EXPECT_TRUE(devicePtr->isPresent(services, system, *chassisPtr));
726 }
727
728 // Test where PresenceDetection was specified in constructor: Is present
729 {
730 // Create PresenceDetection. Indicates device is present.
731 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
732 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
733 std::vector<std::unique_ptr<Action>> actions{};
734 actions.emplace_back(std::move(action));
735 std::unique_ptr<PresenceDetection> presenceDetection =
736 std::make_unique<PresenceDetection>(std::move(actions));
737
738 // Create Device
739 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
740 std::unique_ptr<Device> device = std::make_unique<Device>(
741 "reg1", true,
742 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
743 std::move(i2cInterface), std::move(presenceDetection));
744 Device* devicePtr = device.get();
745
746 // Create Chassis that contains Device
747 std::vector<std::unique_ptr<Device>> devices{};
748 devices.emplace_back(std::move(device));
749 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500750 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600751 Chassis* chassisPtr = chassis.get();
752
753 // Create System that contains Chassis
754 std::vector<std::unique_ptr<Rule>> rules{};
755 std::vector<std::unique_ptr<Chassis>> chassisVec{};
756 chassisVec.emplace_back(std::move(chassis));
757 System system{std::move(rules), std::move(chassisVec)};
758
759 // Create MockServices
760 MockServices services{};
761
762 // PresenceDetection::execute() and isPresent() should return true
763 EXPECT_TRUE(devicePtr->isPresent(services, system, *chassisPtr));
764 }
765
766 // Test where PresenceDetection was specified in constructor: Is not present
767 {
768 // Create PresenceDetection. Indicates device is not present.
769 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
770 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
771 std::vector<std::unique_ptr<Action>> actions{};
772 actions.emplace_back(std::move(action));
773 std::unique_ptr<PresenceDetection> presenceDetection =
774 std::make_unique<PresenceDetection>(std::move(actions));
775
776 // Create Device
777 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
778 std::unique_ptr<Device> device = std::make_unique<Device>(
779 "reg1", true,
780 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
781 std::move(i2cInterface), std::move(presenceDetection));
782 Device* devicePtr = device.get();
783
784 // Create Chassis that contains Device
785 std::vector<std::unique_ptr<Device>> devices{};
786 devices.emplace_back(std::move(device));
787 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500788 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600789 Chassis* chassisPtr = chassis.get();
790
791 // Create System that contains Chassis
792 std::vector<std::unique_ptr<Rule>> rules{};
793 std::vector<std::unique_ptr<Chassis>> chassisVec{};
794 chassisVec.emplace_back(std::move(chassis));
795 System system{std::move(rules), std::move(chassisVec)};
796
797 // Create MockServices
798 MockServices services{};
799
800 // PresenceDetection::execute() and isPresent() should return false
801 EXPECT_FALSE(devicePtr->isPresent(services, system, *chassisPtr));
802 }
803}
804
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500805TEST(DeviceTests, IsRegulator)
806{
Bob Kinga76898f2020-10-13 15:08:33 +0800807 Device device{
808 "vdd_reg", false,
809 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
810 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500811 EXPECT_EQ(device.isRegulator(), false);
812}
Bob King8e1cd0b2020-07-08 13:30:27 +0800813
814TEST(DeviceTests, MonitorSensors)
815{
Shawn McCarney48033bf2021-01-27 17:56:49 -0600816 // Test where device is not present
Bob King8e1cd0b2020-07-08 13:30:27 +0800817 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500818 // Create mock services. No Sensors methods should be called.
Bob King8a552922020-08-05 17:02:31 +0800819 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500820 MockSensors& sensors = services.getMockSensors();
821 EXPECT_CALL(sensors, startRail).Times(0);
822 EXPECT_CALL(sensors, setValue).Times(0);
823 EXPECT_CALL(sensors, endRail).Times(0);
Bob King8a552922020-08-05 17:02:31 +0800824
Shawn McCarney17bac892021-05-08 07:55:52 -0500825 // Create SensorMonitoring. Action inside it should not be executed.
826 std::unique_ptr<MockAction> sensAction = std::make_unique<MockAction>();
827 EXPECT_CALL(*sensAction, execute).Times(0);
828 std::vector<std::unique_ptr<Action>> sensActions{};
829 sensActions.emplace_back(std::move(sensAction));
Bob King8e1cd0b2020-07-08 13:30:27 +0800830 std::unique_ptr<SensorMonitoring> sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500831 std::make_unique<SensorMonitoring>(std::move(sensActions));
Bob King8e1cd0b2020-07-08 13:30:27 +0800832
833 // Create Rail
834 std::unique_ptr<Configuration> configuration{};
835 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500836 "vddr1", std::move(configuration), std::move(sensorMonitoring));
837
838 // Create PresenceDetection. Indicates device is not present.
839 std::unique_ptr<MockAction> presAction = std::make_unique<MockAction>();
840 EXPECT_CALL(*presAction, execute).Times(1).WillOnce(Return(false));
841 std::vector<std::unique_ptr<Action>> presActions{};
842 presActions.emplace_back(std::move(presAction));
843 std::unique_ptr<PresenceDetection> presenceDetection =
844 std::make_unique<PresenceDetection>(std::move(presActions));
Bob King8e1cd0b2020-07-08 13:30:27 +0800845
846 // Create Device
Shawn McCarney17bac892021-05-08 07:55:52 -0500847 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Bob King8e1cd0b2020-07-08 13:30:27 +0800848 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500849 std::vector<std::unique_ptr<Rail>> rails{};
850 rails.emplace_back(std::move(rail));
Bob King8e1cd0b2020-07-08 13:30:27 +0800851 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800852 "reg1", true,
853 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Bob King8e1cd0b2020-07-08 13:30:27 +0800854 std::move(i2cInterface), std::move(presenceDetection),
855 std::move(deviceConfiguration), std::move(rails));
856 Device* devicePtr = device.get();
857
858 // Create Chassis that contains Device
859 std::vector<std::unique_ptr<Device>> devices{};
860 devices.emplace_back(std::move(device));
861 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500862 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
Bob King8e1cd0b2020-07-08 13:30:27 +0800863 Chassis* chassisPtr = chassis.get();
864
865 // Create System that contains Chassis
866 std::vector<std::unique_ptr<Rule>> rules{};
867 std::vector<std::unique_ptr<Chassis>> chassisVec{};
868 chassisVec.emplace_back(std::move(chassis));
869 System system{std::move(rules), std::move(chassisVec)};
870
Shawn McCarney17bac892021-05-08 07:55:52 -0500871 // Call monitorSensors(). Should do nothing.
872 devicePtr->monitorSensors(services, system, *chassisPtr);
873 }
874
875 // Test where Rails were not specified in constructor
876 {
877 // Create mock services. No Sensors methods should be called.
878 MockServices services{};
879 MockSensors& sensors = services.getMockSensors();
880 EXPECT_CALL(sensors, startRail).Times(0);
881 EXPECT_CALL(sensors, setValue).Times(0);
882 EXPECT_CALL(sensors, endRail).Times(0);
883
884 // Create Device
885 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
886 std::unique_ptr<Device> device = std::make_unique<Device>(
887 "reg1", true,
888 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
889 std::move(i2cInterface));
890 Device* devicePtr = device.get();
891
892 // Create Chassis that contains Device
893 std::vector<std::unique_ptr<Device>> devices{};
894 devices.emplace_back(std::move(device));
895 std::unique_ptr<Chassis> chassis =
896 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
897 Chassis* chassisPtr = chassis.get();
898
899 // Create System that contains Chassis
900 std::vector<std::unique_ptr<Rule>> rules{};
901 std::vector<std::unique_ptr<Chassis>> chassisVec{};
902 chassisVec.emplace_back(std::move(chassis));
903 System system{std::move(rules), std::move(chassisVec)};
904
905 // Call monitorSensors(). Should do nothing.
906 devicePtr->monitorSensors(services, system, *chassisPtr);
907 }
908
909 // Test where Rails were specified in constructor
910 {
911 // Create mock services. Set Sensors service expectations.
912 MockServices services{};
913 MockSensors& sensors = services.getMockSensors();
914 EXPECT_CALL(sensors, startRail("vdd0",
915 "/xyz/openbmc_project/inventory/system/"
916 "chassis/motherboard/reg1",
917 chassisInvPath))
918 .Times(1);
919 EXPECT_CALL(sensors, startRail("vio0",
920 "/xyz/openbmc_project/inventory/system/"
921 "chassis/motherboard/reg1",
922 chassisInvPath))
923 .Times(1);
924 EXPECT_CALL(sensors, setValue).Times(0);
925 EXPECT_CALL(sensors, endRail(false)).Times(2);
926
927 std::vector<std::unique_ptr<Rail>> rails{};
928
929 // Create Rail vdd0
930 {
931 // Create SensorMonitoring for Rail
932 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
933 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
934 std::vector<std::unique_ptr<Action>> actions{};
935 actions.emplace_back(std::move(action));
936 std::unique_ptr<SensorMonitoring> sensorMonitoring =
937 std::make_unique<SensorMonitoring>(std::move(actions));
938
939 // Create Rail
940 std::unique_ptr<Configuration> configuration{};
941 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
942 "vdd0", std::move(configuration), std::move(sensorMonitoring));
943 rails.emplace_back(std::move(rail));
944 }
945
946 // Create Rail vio0
947 {
948 // Create SensorMonitoring for Rail
949 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
950 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
951 std::vector<std::unique_ptr<Action>> actions{};
952 actions.emplace_back(std::move(action));
953 std::unique_ptr<SensorMonitoring> sensorMonitoring =
954 std::make_unique<SensorMonitoring>(std::move(actions));
955
956 // Create Rail
957 std::unique_ptr<Configuration> configuration{};
958 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
959 "vio0", std::move(configuration), std::move(sensorMonitoring));
960 rails.emplace_back(std::move(rail));
961 }
962
963 // Create Device that contains Rails
964 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
965 std::unique_ptr<PresenceDetection> presenceDetection{};
966 std::unique_ptr<Configuration> configuration{};
967 std::unique_ptr<Device> device = std::make_unique<Device>(
968 "reg1", true,
969 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
970 std::move(i2cInterface), std::move(presenceDetection),
971 std::move(configuration), std::move(rails));
972 Device* devicePtr = device.get();
973
974 // Create Chassis that contains Device
975 std::vector<std::unique_ptr<Device>> devices{};
976 devices.emplace_back(std::move(device));
977 std::unique_ptr<Chassis> chassis =
978 std::make_unique<Chassis>(1, chassisInvPath, std::move(devices));
979 Chassis* chassisPtr = chassis.get();
980
981 // Create System that contains Chassis
982 std::vector<std::unique_ptr<Rule>> rules{};
983 std::vector<std::unique_ptr<Chassis>> chassisVec{};
984 chassisVec.emplace_back(std::move(chassis));
985 System system{std::move(rules), std::move(chassisVec)};
986
987 // Call monitorSensors(). Should monitor sensors in both rails.
Bob King8a552922020-08-05 17:02:31 +0800988 devicePtr->monitorSensors(services, system, *chassisPtr);
Bob King8e1cd0b2020-07-08 13:30:27 +0800989 }
990}