blob: be353f353ba1534aaef1ce6094832d54b0074f2b [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 McCarney32252592021-09-08 15:29:36 -050028#include "phase_fault_detection.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050029#include "presence_detection.hpp"
30#include "rail.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050031#include "rule.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050032#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050033#include "sensors.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050034#include "system.hpp"
Shawn McCarney371e2442021-05-14 14:18:07 -050035#include "test_sdbus_error.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050036#include "test_utils.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060037
38#include <memory>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050039#include <optional>
Shawn McCarney525e20c2020-04-14 11:05:39 -050040#include <string>
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060041#include <utility>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050042#include <vector>
Shawn McCarneya2461b32019-10-24 18:53:01 -050043
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050044#include <gmock/gmock.h>
Shawn McCarneya2461b32019-10-24 18:53:01 -050045#include <gtest/gtest.h>
46
47using namespace phosphor::power::regulators;
Shawn McCarney8a3afd72020-03-12 14:28:44 -050048using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060049
Bob King8e1cd0b2020-07-08 13:30:27 +080050using ::testing::A;
Shawn McCarney81a2f902021-03-23 21:41:34 -050051using ::testing::Ref;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050052using ::testing::Return;
Shawn McCarneyb4d18a42020-06-02 10:27:05 -050053using ::testing::Throw;
Bob King8e1cd0b2020-07-08 13:30:27 +080054using ::testing::TypedEq;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050055
Shawn McCarney2874e902021-09-09 10:03:59 -050056class DeviceTests : public ::testing::Test
57{
58 public:
59 /**
60 * Constructor.
61 *
62 * Creates the Chassis and System objects needed for calling some Device
63 * methods.
64 */
65 DeviceTests() : ::testing::Test{}
66 {
67 // Create Chassis
68 auto chassis = std::make_unique<Chassis>(1, chassisInvPath);
69 this->chassis = chassis.get();
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050070
Shawn McCarney2874e902021-09-09 10:03:59 -050071 // Create System
72 std::vector<std::unique_ptr<Rule>> rules{};
73 std::vector<std::unique_ptr<Chassis>> chassisVec{};
74 chassisVec.emplace_back(std::move(chassis));
75 this->system =
76 std::make_unique<System>(std::move(rules), std::move(chassisVec));
77 }
78
79 protected:
80 const std::string deviceInvPath{
81 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2"};
82 const std::string chassisInvPath{
83 "/xyz/openbmc_project/inventory/system/chassis"};
84
85 // Note: This pointer does NOT need to be explicitly deleted. The Chassis
86 // object is owned by the System object and will be automatically deleted.
87 Chassis* chassis{nullptr};
88
89 std::unique_ptr<System> system{};
90};
91
92TEST_F(DeviceTests, Constructor)
Shawn McCarneya2461b32019-10-24 18:53:01 -050093{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050094 // Test where only required parameters are specified
95 {
96 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
97 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
Shawn McCarney2874e902021-09-09 10:03:59 -050098 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050099 EXPECT_EQ(device.getID(), "vdd_reg");
100 EXPECT_EQ(device.isRegulator(), true);
Shawn McCarney2874e902021-09-09 10:03:59 -0500101 EXPECT_EQ(device.getFRU(), deviceInvPath);
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500102 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
103 EXPECT_EQ(device.getPresenceDetection(), nullptr);
104 EXPECT_EQ(device.getConfiguration(), nullptr);
Shawn McCarney32252592021-09-08 15:29:36 -0500105 EXPECT_EQ(device.getPhaseFaultDetection(), nullptr);
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500106 EXPECT_EQ(device.getRails().size(), 0);
107 }
108
109 // Test where all parameters are specified
110 {
111 // Create I2CInterface
112 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
113 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
114
115 // Create PresenceDetection
116 std::vector<std::unique_ptr<Action>> actions{};
117 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500118 auto presenceDetection =
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500119 std::make_unique<PresenceDetection>(std::move(actions));
120
121 // Create Configuration
122 std::optional<double> volts{};
123 actions.clear();
124 actions.push_back(std::make_unique<MockAction>());
125 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500126 auto configuration =
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500127 std::make_unique<Configuration>(volts, std::move(actions));
128
Shawn McCarney32252592021-09-08 15:29:36 -0500129 // Create PhaseFaultDetection
130 actions.clear();
131 actions.push_back(std::make_unique<MockAction>());
132 actions.push_back(std::make_unique<MockAction>());
133 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500134 auto phaseFaultDetection =
Shawn McCarney32252592021-09-08 15:29:36 -0500135 std::make_unique<PhaseFaultDetection>(std::move(actions));
136
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500137 // Create vector of Rail objects
138 std::vector<std::unique_ptr<Rail>> rails{};
139 rails.push_back(std::make_unique<Rail>("vdd0"));
140 rails.push_back(std::make_unique<Rail>("vdd1"));
141
142 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500143 Device device{"vdd_reg",
144 false,
145 deviceInvPath,
146 std::move(i2cInterface),
147 std::move(presenceDetection),
148 std::move(configuration),
149 std::move(phaseFaultDetection),
150 std::move(rails)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500151 EXPECT_EQ(device.getID(), "vdd_reg");
152 EXPECT_EQ(device.isRegulator(), false);
Shawn McCarney2874e902021-09-09 10:03:59 -0500153 EXPECT_EQ(device.getFRU(), deviceInvPath);
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500154 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
155 EXPECT_NE(device.getPresenceDetection(), nullptr);
156 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
157 EXPECT_NE(device.getConfiguration(), nullptr);
158 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), false);
159 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
Shawn McCarney32252592021-09-08 15:29:36 -0500160 EXPECT_NE(device.getPhaseFaultDetection(), nullptr);
161 EXPECT_EQ(device.getPhaseFaultDetection()->getActions().size(), 3);
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500162 EXPECT_EQ(device.getRails().size(), 2);
163 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500164}
165
Shawn McCarney2874e902021-09-09 10:03:59 -0500166TEST_F(DeviceTests, AddToIDMap)
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500167{
168 std::unique_ptr<PresenceDetection> presenceDetection{};
169 std::unique_ptr<Configuration> configuration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500170 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500171
172 // Create vector of Rail objects
173 std::vector<std::unique_ptr<Rail>> rails{};
174 rails.push_back(std::make_unique<Rail>("vdd0"));
175 rails.push_back(std::make_unique<Rail>("vdd1"));
176
177 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500178 Device device{"vdd_reg",
179 false,
180 deviceInvPath,
181 std::move(createI2CInterface()),
182 std::move(presenceDetection),
183 std::move(configuration),
184 std::move(phaseFaultDetection),
185 std::move(rails)};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500186
187 // Add Device and Rail objects to an IDMap
188 IDMap idMap{};
189 device.addToIDMap(idMap);
190
191 // Verify Device is in the IDMap
192 EXPECT_NO_THROW(idMap.getDevice("vdd_reg"));
193 EXPECT_THROW(idMap.getDevice("vio_reg"), std::invalid_argument);
194
195 // Verify all Rails are in the IDMap
196 EXPECT_NO_THROW(idMap.getRail("vdd0"));
197 EXPECT_NO_THROW(idMap.getRail("vdd1"));
198 EXPECT_THROW(idMap.getRail("vdd2"), std::invalid_argument);
199}
200
Shawn McCarney2874e902021-09-09 10:03:59 -0500201TEST_F(DeviceTests, ClearCache)
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600202{
203 // Test where Device does not contain a PresenceDetection object
204 try
205 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500206 Device device{"vdd_reg", false, deviceInvPath,
207 std::move(createI2CInterface())};
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600208 device.clearCache();
209 }
210 catch (...)
211 {
212 ADD_FAILURE() << "Should not have caught exception.";
213 }
214
215 // Test where Device contains a PresenceDetection object
216 {
217 // Create PresenceDetection
218 std::vector<std::unique_ptr<Action>> actions{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500219 auto presenceDetection =
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600220 std::make_unique<PresenceDetection>(std::move(actions));
221 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
222
223 // Create Device
224 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500225 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface),
226 std::move(presenceDetection)};
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600227
228 // Cache presence value in PresenceDetection
229 MockServices services{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500230 presenceDetectionPtr->execute(services, *system, *chassis, device);
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600231 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
232
233 // Clear cached data in Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500234 device.clearCache();
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600235
236 // Verify presence value no longer cached in PresenceDetection
237 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
238 }
239}
240
Shawn McCarney2874e902021-09-09 10:03:59 -0500241TEST_F(DeviceTests, ClearErrorHistory)
Shawn McCarney371e2442021-05-14 14:18:07 -0500242{
243 // Create SensorMonitoring. Will fail with a DBus exception.
Shawn McCarney2874e902021-09-09 10:03:59 -0500244 auto action = std::make_unique<MockAction>();
Shawn McCarney371e2442021-05-14 14:18:07 -0500245 EXPECT_CALL(*action, execute)
246 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
247 std::vector<std::unique_ptr<Action>> actions{};
248 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500249 auto sensorMonitoring =
Shawn McCarney371e2442021-05-14 14:18:07 -0500250 std::make_unique<SensorMonitoring>(std::move(actions));
251
252 // Create Rail
253 std::unique_ptr<Configuration> configuration{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500254 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration),
255 std::move(sensorMonitoring));
Shawn McCarney371e2442021-05-14 14:18:07 -0500256
257 // Create Device that contains Rail
Shawn McCarney2874e902021-09-09 10:03:59 -0500258 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney371e2442021-05-14 14:18:07 -0500259 std::unique_ptr<PresenceDetection> presenceDetection{};
260 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500261 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney371e2442021-05-14 14:18:07 -0500262 std::vector<std::unique_ptr<Rail>> rails{};
263 rails.emplace_back(std::move(rail));
Shawn McCarney2874e902021-09-09 10:03:59 -0500264 Device device{"reg2",
265 true,
266 deviceInvPath,
267 std::move(i2cInterface),
268 std::move(presenceDetection),
269 std::move(deviceConfiguration),
270 std::move(phaseFaultDetection),
271 std::move(rails)};
Shawn McCarney371e2442021-05-14 14:18:07 -0500272
273 // Create mock services
274 MockServices services{};
275
276 // Expect Sensors service to be called 5+5=10 times
277 MockSensors& sensors = services.getMockSensors();
278 EXPECT_CALL(sensors, startRail).Times(10);
279 EXPECT_CALL(sensors, setValue).Times(0);
280 EXPECT_CALL(sensors, endRail).Times(10);
281
282 // Expect Journal service to be called 3+3=6 times to log error messages
283 MockJournal& journal = services.getMockJournal();
284 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
285 .Times(6);
286 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
287
288 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
289 MockErrorLogging& errorLogging = services.getMockErrorLogging();
290 EXPECT_CALL(errorLogging, logDBusError).Times(2);
291
292 // Monitor sensors 5 times. Should fail every time, write to journal 3
293 // times, and log one error.
294 for (int i = 1; i <= 5; ++i)
295 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500296 device.monitorSensors(services, *system, *chassis);
Shawn McCarney371e2442021-05-14 14:18:07 -0500297 }
298
299 // Clear error history
Shawn McCarney2874e902021-09-09 10:03:59 -0500300 device.clearErrorHistory();
Shawn McCarney371e2442021-05-14 14:18:07 -0500301
302 // Monitor sensors 5 times again. Should fail every time, write to journal
303 // 3 times, and log one error.
304 for (int i = 1; i <= 5; ++i)
305 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500306 device.monitorSensors(services, *system, *chassis);
Shawn McCarney371e2442021-05-14 14:18:07 -0500307 }
308}
309
Shawn McCarney2874e902021-09-09 10:03:59 -0500310TEST_F(DeviceTests, Close)
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500311{
312 // Test where works: I2C interface is not open
313 {
314 // Create mock I2CInterface
Shawn McCarney2874e902021-09-09 10:03:59 -0500315 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500316 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false));
317 EXPECT_CALL(*i2cInterface, close).Times(0);
318
Bob Kingd692d6d2020-09-14 13:42:57 +0800319 // Create mock services. No logError should occur.
320 MockServices services{};
321 MockJournal& journal = services.getMockJournal();
322 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
323 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
324 .Times(0);
325
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500326 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500327 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500328
329 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800330 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500331 }
332
333 // Test where works: I2C interface is open
334 {
335 // Create mock I2CInterface
Shawn McCarney2874e902021-09-09 10:03:59 -0500336 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500337 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
338 EXPECT_CALL(*i2cInterface, close).Times(1);
339
Bob Kingd692d6d2020-09-14 13:42:57 +0800340 // Create mock services. No logError should occur.
341 MockServices services{};
342 MockJournal& journal = services.getMockJournal();
343 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
344 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
345 .Times(0);
346
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500347 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500348 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500349
350 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800351 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500352 }
353
354 // Test where fails: closing I2C interface fails
355 {
356 // Create mock I2CInterface
Shawn McCarney2874e902021-09-09 10:03:59 -0500357 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500358 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
Shawn McCarney2874e902021-09-09 10:03:59 -0500380 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500381
382 // Close Device
Bob Kingd692d6d2020-09-14 13:42:57 +0800383 device.close(services);
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500384 }
385}
386
Shawn McCarney2874e902021-09-09 10:03:59 -0500387TEST_F(DeviceTests, Configure)
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500388{
Shawn McCarney48033bf2021-01-27 17:56:49 -0600389 // Test where device is not present
390 {
391 // Create mock services. No logging should occur.
392 MockServices services{};
393 MockJournal& journal = services.getMockJournal();
394 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
395 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
396
397 // Create PresenceDetection. Indicates device is not present.
Shawn McCarney2874e902021-09-09 10:03:59 -0500398 std::unique_ptr<PresenceDetection> presenceDetection{};
399 {
400 auto action = std::make_unique<MockAction>();
401 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
402 std::vector<std::unique_ptr<Action>> actions{};
403 actions.emplace_back(std::move(action));
404 presenceDetection =
405 std::make_unique<PresenceDetection>(std::move(actions));
406 }
Shawn McCarney48033bf2021-01-27 17:56:49 -0600407
408 // Create Configuration. Action inside it should not be executed.
Shawn McCarney2874e902021-09-09 10:03:59 -0500409 std::unique_ptr<Configuration> configuration{};
410 {
411 std::optional<double> volts{};
412 auto action = std::make_unique<MockAction>();
413 EXPECT_CALL(*action, execute).Times(0);
414 std::vector<std::unique_ptr<Action>> actions{};
415 actions.emplace_back(std::move(action));
416 configuration =
417 std::make_unique<Configuration>(volts, std::move(actions));
418 }
Shawn McCarney48033bf2021-01-27 17:56:49 -0600419
420 // Create Device
421 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500422 Device device{"reg2",
423 true,
424 deviceInvPath,
425 std::move(i2cInterface),
426 std::move(presenceDetection),
427 std::move(configuration)};
Shawn McCarney48033bf2021-01-27 17:56:49 -0600428
429 // Call configure(). Should do nothing.
Shawn McCarney2874e902021-09-09 10:03:59 -0500430 device.configure(services, *system, *chassis);
Shawn McCarney48033bf2021-01-27 17:56:49 -0600431 }
432
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500433 // Test where Configuration and Rails were not specified in constructor
434 {
Bob King5cfe5102020-07-30 16:26:18 +0800435 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +0800436 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800437 MockJournal& journal = services.getMockJournal();
438 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
439 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800440
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500441 // Create Device
442 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500443 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500444
Bob King5cfe5102020-07-30 16:26:18 +0800445 // Call configure().
Shawn McCarney2874e902021-09-09 10:03:59 -0500446 device.configure(services, *system, *chassis);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500447 }
448
449 // Test where Configuration and Rails were specified in constructor
450 {
451 std::vector<std::unique_ptr<Rail>> rails{};
452
Bob King5cfe5102020-07-30 16:26:18 +0800453 // Create mock services. Expect logDebug() to be called.
454 // For the Device and both Rails, should execute the Configuration
455 // and log a debug message.
456 MockServices services{};
457 MockJournal& journal = services.getMockJournal();
Shawn McCarney2874e902021-09-09 10:03:59 -0500458 EXPECT_CALL(journal, logDebug("Configuring reg2")).Times(1);
Bob King5cfe5102020-07-30 16:26:18 +0800459 EXPECT_CALL(journal, logDebug("Configuring vdd0: volts=1.300000"))
460 .Times(1);
461 EXPECT_CALL(journal, logDebug("Configuring vio0: volts=3.200000"))
462 .Times(1);
463 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
464
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500465 // Create Rail vdd0
466 {
467 // Create Configuration for Rail
468 std::optional<double> volts{1.3};
Shawn McCarney2874e902021-09-09 10:03:59 -0500469 auto action = std::make_unique<MockAction>();
Shawn McCarneyeb7bec42020-04-14 09:38:15 -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 McCarney2874e902021-09-09 10:03:59 -0500473 auto configuration =
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500474 std::make_unique<Configuration>(volts, std::move(actions));
475
476 // Create Rail
Shawn McCarney2874e902021-09-09 10:03:59 -0500477 auto rail =
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500478 std::make_unique<Rail>("vdd0", std::move(configuration));
479 rails.emplace_back(std::move(rail));
480 }
481
482 // Create Rail vio0
483 {
484 // Create Configuration for Rail
485 std::optional<double> volts{3.2};
Shawn McCarney2874e902021-09-09 10:03:59 -0500486 auto action = std::make_unique<MockAction>();
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500487 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
488 std::vector<std::unique_ptr<Action>> actions{};
489 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500490 auto configuration =
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500491 std::make_unique<Configuration>(volts, std::move(actions));
492
493 // Create Rail
Shawn McCarney2874e902021-09-09 10:03:59 -0500494 auto rail =
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500495 std::make_unique<Rail>("vio0", std::move(configuration));
496 rails.emplace_back(std::move(rail));
497 }
498
499 // Create Configuration for Device
500 std::optional<double> volts{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500501 auto action = std::make_unique<MockAction>();
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500502 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
503 std::vector<std::unique_ptr<Action>> actions{};
504 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500505 auto configuration =
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500506 std::make_unique<Configuration>(volts, std::move(actions));
507
508 // Create Device
509 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
510 std::unique_ptr<PresenceDetection> presenceDetection{};
Shawn McCarney32252592021-09-08 15:29:36 -0500511 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500512 Device device{"reg2",
513 true,
514 deviceInvPath,
515 std::move(i2cInterface),
516 std::move(presenceDetection),
517 std::move(configuration),
518 std::move(phaseFaultDetection),
519 std::move(rails)};
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500520
Bob King5cfe5102020-07-30 16:26:18 +0800521 // Call configure().
Shawn McCarney2874e902021-09-09 10:03:59 -0500522 device.configure(services, *system, *chassis);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500523 }
524}
525
Shawn McCarney2874e902021-09-09 10:03:59 -0500526TEST_F(DeviceTests, GetConfiguration)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500527{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500528 // Test where Configuration was not specified in constructor
529 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500530 Device device{"vdd_reg", true, deviceInvPath,
531 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500532 EXPECT_EQ(device.getConfiguration(), nullptr);
533 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600534
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500535 // Test where Configuration was specified in constructor
536 {
537 std::unique_ptr<PresenceDetection> presenceDetection{};
538
539 // Create Configuration
540 std::optional<double> volts{3.2};
541 std::vector<std::unique_ptr<Action>> actions{};
542 actions.push_back(std::make_unique<MockAction>());
543 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500544 auto configuration =
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500545 std::make_unique<Configuration>(volts, std::move(actions));
546
547 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500548 Device device{"vdd_reg",
549 true,
550 deviceInvPath,
551 std::move(createI2CInterface()),
552 std::move(presenceDetection),
553 std::move(configuration)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500554 EXPECT_NE(device.getConfiguration(), nullptr);
555 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true);
556 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2);
557 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
558 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600559}
560
Shawn McCarney2874e902021-09-09 10:03:59 -0500561TEST_F(DeviceTests, GetFRU)
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600562{
Shawn McCarney2874e902021-09-09 10:03:59 -0500563 Device device{"vdd_reg", true, deviceInvPath,
564 std::move(createI2CInterface())};
565 EXPECT_EQ(device.getFRU(), deviceInvPath);
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600566}
567
Shawn McCarney2874e902021-09-09 10:03:59 -0500568TEST_F(DeviceTests, GetI2CInterface)
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600569{
570 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
571 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
Shawn McCarney2874e902021-09-09 10:03:59 -0500572 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600573 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
Shawn McCarneya2461b32019-10-24 18:53:01 -0500574}
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500575
Shawn McCarney2874e902021-09-09 10:03:59 -0500576TEST_F(DeviceTests, GetID)
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500577{
Shawn McCarney2874e902021-09-09 10:03:59 -0500578 Device device{"vdd_reg", false, deviceInvPath,
579 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500580 EXPECT_EQ(device.getID(), "vdd_reg");
581}
582
Shawn McCarney2874e902021-09-09 10:03:59 -0500583TEST_F(DeviceTests, GetPhaseFaultDetection)
Shawn McCarney32252592021-09-08 15:29:36 -0500584{
585 // Test where PhaseFaultDetection was not specified in constructor
586 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500587 Device device{"vdd_reg", true, deviceInvPath,
588 std::move(createI2CInterface())};
Shawn McCarney32252592021-09-08 15:29:36 -0500589 EXPECT_EQ(device.getPhaseFaultDetection(), nullptr);
590 }
591
592 // Test where PhaseFaultDetection was specified in constructor
593 {
594 // Create PhaseFaultDetection
595 std::vector<std::unique_ptr<Action>> actions{};
596 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500597 auto phaseFaultDetection =
Shawn McCarney32252592021-09-08 15:29:36 -0500598 std::make_unique<PhaseFaultDetection>(std::move(actions));
599
600 // Create Device
601 std::unique_ptr<PresenceDetection> presenceDetection{};
602 std::unique_ptr<Configuration> configuration{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500603 Device device{"vdd_reg",
604 false,
605 deviceInvPath,
606 std::move(createI2CInterface()),
607 std::move(presenceDetection),
608 std::move(configuration),
609 std::move(phaseFaultDetection)};
Shawn McCarney32252592021-09-08 15:29:36 -0500610 EXPECT_NE(device.getPhaseFaultDetection(), nullptr);
611 EXPECT_EQ(device.getPhaseFaultDetection()->getActions().size(), 1);
612 }
613}
614
Shawn McCarney2874e902021-09-09 10:03:59 -0500615TEST_F(DeviceTests, GetPresenceDetection)
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500616{
617 // Test where PresenceDetection was not specified in constructor
618 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500619 Device device{"vdd_reg", true, deviceInvPath,
620 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500621 EXPECT_EQ(device.getPresenceDetection(), nullptr);
622 }
623
624 // Test where PresenceDetection was specified in constructor
625 {
626 // Create PresenceDetection
627 std::vector<std::unique_ptr<Action>> actions{};
628 actions.push_back(std::make_unique<MockAction>());
Shawn McCarney2874e902021-09-09 10:03:59 -0500629 auto presenceDetection =
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500630 std::make_unique<PresenceDetection>(std::move(actions));
631
632 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500633 Device device{"vdd_reg", false, deviceInvPath,
634 std::move(createI2CInterface()),
635 std::move(presenceDetection)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500636 EXPECT_NE(device.getPresenceDetection(), nullptr);
637 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
638 }
639}
640
Shawn McCarney2874e902021-09-09 10:03:59 -0500641TEST_F(DeviceTests, GetRails)
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500642{
643 // Test where no rails were specified in constructor
644 {
Shawn McCarney2874e902021-09-09 10:03:59 -0500645 Device device{"vdd_reg", true, deviceInvPath,
646 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500647 EXPECT_EQ(device.getRails().size(), 0);
648 }
649
650 // Test where rails were specified in constructor
651 {
652 std::unique_ptr<PresenceDetection> presenceDetection{};
653 std::unique_ptr<Configuration> configuration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500654 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500655
656 // Create vector of Rail objects
657 std::vector<std::unique_ptr<Rail>> rails{};
658 rails.push_back(std::make_unique<Rail>("vdd0"));
659 rails.push_back(std::make_unique<Rail>("vdd1"));
660
661 // Create Device
Shawn McCarney2874e902021-09-09 10:03:59 -0500662 Device device{"vdd_reg",
663 false,
664 deviceInvPath,
665 std::move(createI2CInterface()),
666 std::move(presenceDetection),
667 std::move(configuration),
668 std::move(phaseFaultDetection),
669 std::move(rails)};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500670 EXPECT_EQ(device.getRails().size(), 2);
671 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0");
672 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1");
673 }
674}
675
Shawn McCarney2874e902021-09-09 10:03:59 -0500676TEST_F(DeviceTests, IsPresent)
Shawn McCarney48033bf2021-01-27 17:56:49 -0600677{
678 // Test where PresenceDetection not specified in constructor
679 {
680 // Create Device
681 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500682 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarney48033bf2021-01-27 17:56:49 -0600683
684 // Create MockServices
685 MockServices services{};
686
687 // Since no PresenceDetection defined, isPresent() should return true
Shawn McCarney2874e902021-09-09 10:03:59 -0500688 EXPECT_TRUE(device.isPresent(services, *system, *chassis));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600689 }
690
691 // Test where PresenceDetection was specified in constructor: Is present
692 {
693 // Create PresenceDetection. Indicates device is present.
Shawn McCarney2874e902021-09-09 10:03:59 -0500694 auto action = std::make_unique<MockAction>();
Shawn McCarney48033bf2021-01-27 17:56:49 -0600695 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
696 std::vector<std::unique_ptr<Action>> actions{};
697 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500698 auto presenceDetection =
Shawn McCarney48033bf2021-01-27 17:56:49 -0600699 std::make_unique<PresenceDetection>(std::move(actions));
700
701 // Create Device
702 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500703 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface),
704 std::move(presenceDetection)};
Shawn McCarney48033bf2021-01-27 17:56:49 -0600705
706 // Create MockServices
707 MockServices services{};
708
709 // PresenceDetection::execute() and isPresent() should return true
Shawn McCarney2874e902021-09-09 10:03:59 -0500710 EXPECT_TRUE(device.isPresent(services, *system, *chassis));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600711 }
712
713 // Test where PresenceDetection was specified in constructor: Is not present
714 {
715 // Create PresenceDetection. Indicates device is not present.
Shawn McCarney2874e902021-09-09 10:03:59 -0500716 auto action = std::make_unique<MockAction>();
Shawn McCarney48033bf2021-01-27 17:56:49 -0600717 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
718 std::vector<std::unique_ptr<Action>> actions{};
719 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500720 auto presenceDetection =
Shawn McCarney48033bf2021-01-27 17:56:49 -0600721 std::make_unique<PresenceDetection>(std::move(actions));
722
723 // Create Device
724 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500725 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface),
726 std::move(presenceDetection)};
Shawn McCarney48033bf2021-01-27 17:56:49 -0600727
728 // Create MockServices
729 MockServices services{};
730
731 // PresenceDetection::execute() and isPresent() should return false
Shawn McCarney2874e902021-09-09 10:03:59 -0500732 EXPECT_FALSE(device.isPresent(services, *system, *chassis));
Shawn McCarney48033bf2021-01-27 17:56:49 -0600733 }
734}
735
Shawn McCarney2874e902021-09-09 10:03:59 -0500736TEST_F(DeviceTests, IsRegulator)
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500737{
Shawn McCarney2874e902021-09-09 10:03:59 -0500738 Device device{"vdd_reg", false, deviceInvPath,
739 std::move(createI2CInterface())};
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500740 EXPECT_EQ(device.isRegulator(), false);
741}
Bob King8e1cd0b2020-07-08 13:30:27 +0800742
Shawn McCarney2874e902021-09-09 10:03:59 -0500743TEST_F(DeviceTests, MonitorSensors)
Bob King8e1cd0b2020-07-08 13:30:27 +0800744{
Shawn McCarney48033bf2021-01-27 17:56:49 -0600745 // Test where device is not present
Bob King8e1cd0b2020-07-08 13:30:27 +0800746 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500747 // Create mock services. No Sensors methods should be called.
Bob King8a552922020-08-05 17:02:31 +0800748 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500749 MockSensors& sensors = services.getMockSensors();
750 EXPECT_CALL(sensors, startRail).Times(0);
751 EXPECT_CALL(sensors, setValue).Times(0);
752 EXPECT_CALL(sensors, endRail).Times(0);
Bob King8a552922020-08-05 17:02:31 +0800753
Shawn McCarney17bac892021-05-08 07:55:52 -0500754 // Create SensorMonitoring. Action inside it should not be executed.
Shawn McCarney2874e902021-09-09 10:03:59 -0500755 std::unique_ptr<SensorMonitoring> sensorMonitoring{};
756 {
757 auto action = std::make_unique<MockAction>();
758 EXPECT_CALL(*action, execute).Times(0);
759 std::vector<std::unique_ptr<Action>> actions{};
760 actions.emplace_back(std::move(action));
761 sensorMonitoring =
762 std::make_unique<SensorMonitoring>(std::move(actions));
763 }
Bob King8e1cd0b2020-07-08 13:30:27 +0800764
765 // Create Rail
766 std::unique_ptr<Configuration> configuration{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500767 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration),
768 std::move(sensorMonitoring));
Shawn McCarney17bac892021-05-08 07:55:52 -0500769
770 // Create PresenceDetection. Indicates device is not present.
Shawn McCarney2874e902021-09-09 10:03:59 -0500771 std::unique_ptr<PresenceDetection> presenceDetection{};
772 {
773 auto action = std::make_unique<MockAction>();
774 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
775 std::vector<std::unique_ptr<Action>> actions{};
776 actions.emplace_back(std::move(action));
777 presenceDetection =
778 std::make_unique<PresenceDetection>(std::move(actions));
779 }
Bob King8e1cd0b2020-07-08 13:30:27 +0800780
781 // Create Device
Shawn McCarney17bac892021-05-08 07:55:52 -0500782 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Bob King8e1cd0b2020-07-08 13:30:27 +0800783 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500784 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500785 std::vector<std::unique_ptr<Rail>> rails{};
786 rails.emplace_back(std::move(rail));
Shawn McCarney2874e902021-09-09 10:03:59 -0500787 Device device{"reg2",
788 true,
789 deviceInvPath,
790 std::move(i2cInterface),
791 std::move(presenceDetection),
792 std::move(deviceConfiguration),
793 std::move(phaseFaultDetection),
794 std::move(rails)};
Bob King8e1cd0b2020-07-08 13:30:27 +0800795
Shawn McCarney17bac892021-05-08 07:55:52 -0500796 // Call monitorSensors(). Should do nothing.
Shawn McCarney2874e902021-09-09 10:03:59 -0500797 device.monitorSensors(services, *system, *chassis);
Shawn McCarney17bac892021-05-08 07:55:52 -0500798 }
799
800 // Test where Rails were not specified in constructor
801 {
802 // Create mock services. No Sensors methods should be called.
803 MockServices services{};
804 MockSensors& sensors = services.getMockSensors();
805 EXPECT_CALL(sensors, startRail).Times(0);
806 EXPECT_CALL(sensors, setValue).Times(0);
807 EXPECT_CALL(sensors, endRail).Times(0);
808
809 // Create Device
810 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
Shawn McCarney2874e902021-09-09 10:03:59 -0500811 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)};
Shawn McCarney17bac892021-05-08 07:55:52 -0500812
813 // Call monitorSensors(). Should do nothing.
Shawn McCarney2874e902021-09-09 10:03:59 -0500814 device.monitorSensors(services, *system, *chassis);
Shawn McCarney17bac892021-05-08 07:55:52 -0500815 }
816
817 // Test where Rails were specified in constructor
818 {
819 // Create mock services. Set Sensors service expectations.
820 MockServices services{};
821 MockSensors& sensors = services.getMockSensors();
Shawn McCarney2874e902021-09-09 10:03:59 -0500822 EXPECT_CALL(sensors, startRail("vdd0", deviceInvPath, chassisInvPath))
Shawn McCarney17bac892021-05-08 07:55:52 -0500823 .Times(1);
Shawn McCarney2874e902021-09-09 10:03:59 -0500824 EXPECT_CALL(sensors, startRail("vio0", deviceInvPath, chassisInvPath))
Shawn McCarney17bac892021-05-08 07:55:52 -0500825 .Times(1);
826 EXPECT_CALL(sensors, setValue).Times(0);
827 EXPECT_CALL(sensors, endRail(false)).Times(2);
828
829 std::vector<std::unique_ptr<Rail>> rails{};
830
831 // Create Rail vdd0
832 {
833 // Create SensorMonitoring for Rail
Shawn McCarney2874e902021-09-09 10:03:59 -0500834 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500835 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
836 std::vector<std::unique_ptr<Action>> actions{};
837 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500838 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500839 std::make_unique<SensorMonitoring>(std::move(actions));
840
841 // Create Rail
842 std::unique_ptr<Configuration> configuration{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500843 auto rail = std::make_unique<Rail>("vdd0", std::move(configuration),
844 std::move(sensorMonitoring));
Shawn McCarney17bac892021-05-08 07:55:52 -0500845 rails.emplace_back(std::move(rail));
846 }
847
848 // Create Rail vio0
849 {
850 // Create SensorMonitoring for Rail
Shawn McCarney2874e902021-09-09 10:03:59 -0500851 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500852 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
853 std::vector<std::unique_ptr<Action>> actions{};
854 actions.emplace_back(std::move(action));
Shawn McCarney2874e902021-09-09 10:03:59 -0500855 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500856 std::make_unique<SensorMonitoring>(std::move(actions));
857
858 // Create Rail
859 std::unique_ptr<Configuration> configuration{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500860 auto rail = std::make_unique<Rail>("vio0", std::move(configuration),
861 std::move(sensorMonitoring));
Shawn McCarney17bac892021-05-08 07:55:52 -0500862 rails.emplace_back(std::move(rail));
863 }
864
865 // Create Device that contains Rails
866 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
867 std::unique_ptr<PresenceDetection> presenceDetection{};
868 std::unique_ptr<Configuration> configuration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500869 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney2874e902021-09-09 10:03:59 -0500870 Device device{"reg2",
871 true,
872 deviceInvPath,
873 std::move(i2cInterface),
874 std::move(presenceDetection),
875 std::move(configuration),
876 std::move(phaseFaultDetection),
877 std::move(rails)};
Shawn McCarney17bac892021-05-08 07:55:52 -0500878
879 // Call monitorSensors(). Should monitor sensors in both rails.
Shawn McCarney2874e902021-09-09 10:03:59 -0500880 device.monitorSensors(services, *system, *chassis);
Bob King8e1cd0b2020-07-08 13:30:27 +0800881 }
882}