blob: 3b978cae77cd558858a30f66c35b840ca77f1cc6 [file] [log] [blame]
Shawn McCarney8a3afd72020-03-12 14:28:44 -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 McCarney525e20c2020-04-14 11:05:39 -050016#include "action.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050017#include "chassis.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050018#include "configuration.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050019#include "device.hpp"
20#include "i2c_interface.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050021#include "id_map.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050022#include "mock_action.hpp"
Shawn McCarney9f3e54e2021-05-14 14:56:13 -050023#include "mock_error_logging.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -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 McCarney050531f2020-06-02 14:17:12 -050027#include "mocked_i2c_interface.hpp"
Shawn McCarney32252592021-09-08 15:29:36 -050028#include "phase_fault_detection.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050029#include "presence_detection.hpp"
30#include "rail.hpp"
31#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 McCarney525e20c2020-04-14 11:05:39 -050034#include "system.hpp"
Shawn McCarney9f3e54e2021-05-14 14:56:13 -050035#include "test_sdbus_error.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050036#include "test_utils.hpp"
37
38#include <memory>
39#include <stdexcept>
Shawn McCarney525e20c2020-04-14 11:05:39 -050040#include <string>
Shawn McCarney8a3afd72020-03-12 14:28:44 -050041#include <utility>
42#include <vector>
43
Bob Kinga2c81a62020-07-08 13:31:16 +080044#include <gmock/gmock.h>
Shawn McCarney8a3afd72020-03-12 14:28:44 -050045#include <gtest/gtest.h>
46
47using namespace phosphor::power::regulators;
48using namespace phosphor::power::regulators::test_utils;
49
Bob Kinga2c81a62020-07-08 13:31:16 +080050using ::testing::A;
Shawn McCarney050531f2020-06-02 14:17:12 -050051using ::testing::Return;
Shawn McCarney9f3e54e2021-05-14 14:56:13 -050052using ::testing::Throw;
Bob Kinga2c81a62020-07-08 13:31:16 +080053using ::testing::TypedEq;
Shawn McCarney050531f2020-06-02 14:17:12 -050054
Shawn McCarney83058602021-09-09 20:52:45 -050055class ChassisTests : public ::testing::Test
56{
57 public:
58 /**
59 * Constructor.
60 *
61 * Creates the System object needed for calling some Chassis methods.
62 */
63 ChassisTests() : ::testing::Test{}
64 {
65 std::vector<std::unique_ptr<Rule>> rules{};
66 std::vector<std::unique_ptr<Chassis>> chassis{};
67 system = std::make_unique<System>(std::move(rules), std::move(chassis));
68 }
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050069
Shawn McCarney83058602021-09-09 20:52:45 -050070 protected:
71 const std::string defaultInventoryPath{
72 "/xyz/openbmc_project/inventory/system/chassis"};
73
74 std::unique_ptr<System> system{};
75};
76
77TEST_F(ChassisTests, Constructor)
Shawn McCarney8a3afd72020-03-12 14:28:44 -050078{
79 // Test where works: Only required parameters are specified
80 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050081 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050082 EXPECT_EQ(chassis.getNumber(), 2);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050083 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050084 EXPECT_EQ(chassis.getDevices().size(), 0);
85 }
86
87 // Test where works: All parameters are specified
88 {
89 // Create vector of Device objects
90 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050091 devices.emplace_back(createDevice("vdd_reg1"));
92 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -050093
94 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050095 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050096 EXPECT_EQ(chassis.getNumber(), 1);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050097 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050098 EXPECT_EQ(chassis.getDevices().size(), 2);
99 }
100
101 // Test where fails: Invalid chassis number < 1
102 try
103 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500104 Chassis chassis{0, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500105 ADD_FAILURE() << "Should not have reached this line.";
106 }
107 catch (const std::invalid_argument& e)
108 {
109 EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
110 }
111 catch (...)
112 {
113 ADD_FAILURE() << "Should not have caught exception.";
114 }
115}
116
Shawn McCarney83058602021-09-09 20:52:45 -0500117TEST_F(ChassisTests, AddToIDMap)
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500118{
119 // Create vector of Device objects
120 std::vector<std::unique_ptr<Device>> devices{};
121 devices.emplace_back(createDevice("reg1", {"rail1"}));
122 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
123 devices.emplace_back(createDevice("reg3"));
124
125 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500126 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500127
128 // Add Device and Rail objects within the Chassis to an IDMap
129 IDMap idMap{};
130 chassis.addToIDMap(idMap);
131
132 // Verify all Devices are in the IDMap
133 EXPECT_NO_THROW(idMap.getDevice("reg1"));
134 EXPECT_NO_THROW(idMap.getDevice("reg2"));
135 EXPECT_NO_THROW(idMap.getDevice("reg3"));
136 EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
137
138 // Verify all Rails are in the IDMap
139 EXPECT_NO_THROW(idMap.getRail("rail1"));
140 EXPECT_NO_THROW(idMap.getRail("rail2a"));
141 EXPECT_NO_THROW(idMap.getRail("rail2b"));
142 EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
143}
144
Shawn McCarney83058602021-09-09 20:52:45 -0500145TEST_F(ChassisTests, ClearCache)
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600146{
147 // Create PresenceDetection
148 std::vector<std::unique_ptr<Action>> actions{};
Shawn McCarney83058602021-09-09 20:52:45 -0500149 auto presenceDetection =
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600150 std::make_unique<PresenceDetection>(std::move(actions));
151 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
152
153 // Create Device that contains PresenceDetection
Shawn McCarney83058602021-09-09 20:52:45 -0500154 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
155 auto device = std::make_unique<Device>(
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600156 "reg1", true,
157 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
158 std::move(i2cInterface), std::move(presenceDetection));
159 Device* devicePtr = device.get();
160
161 // Create Chassis that contains Device
162 std::vector<std::unique_ptr<Device>> devices{};
163 devices.emplace_back(std::move(device));
Shawn McCarney83058602021-09-09 20:52:45 -0500164 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600165
166 // Cache presence value in PresenceDetection
167 MockServices services{};
Shawn McCarney83058602021-09-09 20:52:45 -0500168 presenceDetectionPtr->execute(services, *system, chassis, *devicePtr);
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600169 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
170
171 // Clear cached data in Chassis
Shawn McCarney83058602021-09-09 20:52:45 -0500172 chassis.clearCache();
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600173
174 // Verify presence value no longer cached in PresenceDetection
175 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
176}
177
Shawn McCarney83058602021-09-09 20:52:45 -0500178TEST_F(ChassisTests, ClearErrorHistory)
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500179{
180 // Create SensorMonitoring. Will fail with a DBus exception.
Shawn McCarney83058602021-09-09 20:52:45 -0500181 auto action = std::make_unique<MockAction>();
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500182 EXPECT_CALL(*action, execute)
183 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
184 std::vector<std::unique_ptr<Action>> actions{};
185 actions.emplace_back(std::move(action));
Shawn McCarney83058602021-09-09 20:52:45 -0500186 auto sensorMonitoring =
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500187 std::make_unique<SensorMonitoring>(std::move(actions));
188
189 // Create Rail
190 std::unique_ptr<Configuration> configuration{};
Shawn McCarney83058602021-09-09 20:52:45 -0500191 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration),
192 std::move(sensorMonitoring));
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500193
194 // Create Device that contains Rail
Shawn McCarney83058602021-09-09 20:52:45 -0500195 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500196 std::unique_ptr<PresenceDetection> presenceDetection{};
197 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500198 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500199 std::vector<std::unique_ptr<Rail>> rails{};
200 rails.emplace_back(std::move(rail));
Shawn McCarney83058602021-09-09 20:52:45 -0500201 auto device = std::make_unique<Device>(
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500202 "reg1", true,
203 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
204 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500205 std::move(deviceConfiguration), std::move(phaseFaultDetection),
206 std::move(rails));
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500207
208 // Create Chassis that contains Device
209 std::vector<std::unique_ptr<Device>> devices{};
210 devices.emplace_back(std::move(device));
Shawn McCarney83058602021-09-09 20:52:45 -0500211 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500212
213 // Create mock services
214 MockServices services{};
215
216 // Expect Sensors service to be called 5+5=10 times
217 MockSensors& sensors = services.getMockSensors();
218 EXPECT_CALL(sensors, startRail).Times(10);
219 EXPECT_CALL(sensors, setValue).Times(0);
220 EXPECT_CALL(sensors, endRail).Times(10);
221
222 // Expect Journal service to be called 3+3=6 times to log error messages
223 MockJournal& journal = services.getMockJournal();
224 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
225 .Times(6);
226 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
227
228 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
229 MockErrorLogging& errorLogging = services.getMockErrorLogging();
230 EXPECT_CALL(errorLogging, logDBusError).Times(2);
231
232 // Monitor sensors 5 times. Should fail every time, write to journal 3
233 // times, and log one error.
234 for (int i = 1; i <= 5; ++i)
235 {
Shawn McCarney83058602021-09-09 20:52:45 -0500236 chassis.monitorSensors(services, *system);
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500237 }
238
239 // Clear error history
Shawn McCarney83058602021-09-09 20:52:45 -0500240 chassis.clearErrorHistory();
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500241
242 // Monitor sensors 5 times again. Should fail every time, write to journal
243 // 3 times, and log one error.
244 for (int i = 1; i <= 5; ++i)
245 {
Shawn McCarney83058602021-09-09 20:52:45 -0500246 chassis.monitorSensors(services, *system);
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500247 }
248}
249
Shawn McCarney83058602021-09-09 20:52:45 -0500250TEST_F(ChassisTests, CloseDevices)
Shawn McCarney050531f2020-06-02 14:17:12 -0500251{
252 // Test where no devices were specified in constructor
253 {
Bob Kingd692d6d2020-09-14 13:42:57 +0800254 // Create mock services. Expect logDebug() to be called.
255 MockServices services{};
256 MockJournal& journal = services.getMockJournal();
257 EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1);
258
Shawn McCarney050531f2020-06-02 14:17:12 -0500259 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500260 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney050531f2020-06-02 14:17:12 -0500261
262 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800263 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500264 }
265
266 // Test where devices were specified in constructor
267 {
268 std::vector<std::unique_ptr<Device>> devices{};
269
Bob Kingd692d6d2020-09-14 13:42:57 +0800270 // Create mock services. Expect logDebug() to be called.
271 MockServices services{};
272 MockJournal& journal = services.getMockJournal();
273 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
274
Shawn McCarney050531f2020-06-02 14:17:12 -0500275 // Create Device vdd0_reg
276 {
277 // Create mock I2CInterface: isOpen() and close() should be called
Shawn McCarney83058602021-09-09 20:52:45 -0500278 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney050531f2020-06-02 14:17:12 -0500279 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
280 EXPECT_CALL(*i2cInterface, close).Times(1);
281
282 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -0500283 auto device =
Bob Kinga76898f2020-10-13 15:08:33 +0800284 std::make_unique<Device>("vdd0_reg", true,
285 "/xyz/openbmc_project/inventory/"
286 "system/chassis/motherboard/vdd0_reg",
287 std::move(i2cInterface));
Shawn McCarney050531f2020-06-02 14:17:12 -0500288 devices.emplace_back(std::move(device));
289 }
290
291 // Create Device vdd1_reg
292 {
293 // Create mock I2CInterface: isOpen() and close() should be called
Shawn McCarney83058602021-09-09 20:52:45 -0500294 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney050531f2020-06-02 14:17:12 -0500295 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
296 EXPECT_CALL(*i2cInterface, close).Times(1);
297
298 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -0500299 auto device =
Bob Kinga76898f2020-10-13 15:08:33 +0800300 std::make_unique<Device>("vdd1_reg", true,
301 "/xyz/openbmc_project/inventory/"
302 "system/chassis/motherboard/vdd1_reg",
303 std::move(i2cInterface));
Shawn McCarney050531f2020-06-02 14:17:12 -0500304 devices.emplace_back(std::move(device));
305 }
306
307 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500308 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney050531f2020-06-02 14:17:12 -0500309
310 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800311 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500312 }
313}
314
Shawn McCarney83058602021-09-09 20:52:45 -0500315TEST_F(ChassisTests, Configure)
Shawn McCarney525e20c2020-04-14 11:05:39 -0500316{
317 // Test where no devices were specified in constructor
318 {
Bob King5cfe5102020-07-30 16:26:18 +0800319 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800320 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800321 MockJournal& journal = services.getMockJournal();
322 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
323 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
324 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800325
Shawn McCarney525e20c2020-04-14 11:05:39 -0500326 // Create Chassis
Shawn McCarney83058602021-09-09 20:52:45 -0500327 Chassis chassis{1, defaultInventoryPath};
Shawn McCarney525e20c2020-04-14 11:05:39 -0500328
329 // Call configure()
Shawn McCarney83058602021-09-09 20:52:45 -0500330 chassis.configure(services, *system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500331 }
332
333 // Test where devices were specified in constructor
334 {
335 std::vector<std::unique_ptr<Device>> devices{};
336
Bob King5cfe5102020-07-30 16:26:18 +0800337 // Create mock services. Expect logInfo() and logDebug() to be called.
338 MockServices services{};
339 MockJournal& journal = services.getMockJournal();
340 EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1);
341 EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000"))
342 .Times(1);
343 EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000"))
344 .Times(1);
345 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
346
Shawn McCarney525e20c2020-04-14 11:05:39 -0500347 // Create Device vdd0_reg
348 {
349 // Create Configuration
350 std::vector<std::unique_ptr<Action>> actions{};
Shawn McCarney83058602021-09-09 20:52:45 -0500351 auto configuration =
Shawn McCarney525e20c2020-04-14 11:05:39 -0500352 std::make_unique<Configuration>(1.3, std::move(actions));
353
354 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -0500355 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney525e20c2020-04-14 11:05:39 -0500356 std::unique_ptr<PresenceDetection> presenceDetection{};
Shawn McCarney83058602021-09-09 20:52:45 -0500357 auto device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800358 "vdd0_reg", true,
359 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
360 "vdd0_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500361 std::move(i2cInterface), std::move(presenceDetection),
362 std::move(configuration));
363 devices.emplace_back(std::move(device));
364 }
365
366 // Create Device vdd1_reg
367 {
368 // Create Configuration
369 std::vector<std::unique_ptr<Action>> actions{};
Shawn McCarney83058602021-09-09 20:52:45 -0500370 auto configuration =
Shawn McCarney525e20c2020-04-14 11:05:39 -0500371 std::make_unique<Configuration>(1.2, std::move(actions));
372
373 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -0500374 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney525e20c2020-04-14 11:05:39 -0500375 std::unique_ptr<PresenceDetection> presenceDetection{};
Shawn McCarney83058602021-09-09 20:52:45 -0500376 auto device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800377 "vdd1_reg", true,
378 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
379 "vdd1_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500380 std::move(i2cInterface), std::move(presenceDetection),
381 std::move(configuration));
382 devices.emplace_back(std::move(device));
383 }
384
385 // Create Chassis
Shawn McCarney83058602021-09-09 20:52:45 -0500386 Chassis chassis{2, defaultInventoryPath, std::move(devices)};
Shawn McCarney525e20c2020-04-14 11:05:39 -0500387
388 // Call configure()
Shawn McCarney83058602021-09-09 20:52:45 -0500389 chassis.configure(services, *system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500390 }
391}
392
Shawn McCarney83058602021-09-09 20:52:45 -0500393TEST_F(ChassisTests, GetDevices)
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500394{
395 // Test where no devices were specified in constructor
396 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500397 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500398 EXPECT_EQ(chassis.getDevices().size(), 0);
399 }
400
401 // Test where devices were specified in constructor
402 {
403 // Create vector of Device objects
404 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500405 devices.emplace_back(createDevice("vdd_reg1"));
406 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500407
408 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500409 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500410 EXPECT_EQ(chassis.getDevices().size(), 2);
411 EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
412 EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
413 }
414}
415
Shawn McCarney83058602021-09-09 20:52:45 -0500416TEST_F(ChassisTests, GetInventoryPath)
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500417{
418 Chassis chassis{3, defaultInventoryPath};
419 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
420}
421
Shawn McCarney83058602021-09-09 20:52:45 -0500422TEST_F(ChassisTests, GetNumber)
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500423{
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500424 Chassis chassis{3, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500425 EXPECT_EQ(chassis.getNumber(), 3);
426}
Bob Kinga2c81a62020-07-08 13:31:16 +0800427
Shawn McCarney83058602021-09-09 20:52:45 -0500428TEST_F(ChassisTests, MonitorSensors)
Bob Kinga2c81a62020-07-08 13:31:16 +0800429{
430 // Test where no devices were specified in constructor
431 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500432 // Create mock services. No Sensors methods should be called.
Bob King8a552922020-08-05 17:02:31 +0800433 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500434 MockSensors& sensors = services.getMockSensors();
435 EXPECT_CALL(sensors, startRail).Times(0);
436 EXPECT_CALL(sensors, setValue).Times(0);
437 EXPECT_CALL(sensors, endRail).Times(0);
Bob King8a552922020-08-05 17:02:31 +0800438
Bob Kinga2c81a62020-07-08 13:31:16 +0800439 // Create Chassis
Shawn McCarney83058602021-09-09 20:52:45 -0500440 Chassis chassis{1, defaultInventoryPath};
Bob Kinga2c81a62020-07-08 13:31:16 +0800441
442 // Call monitorSensors(). Should do nothing.
Shawn McCarney83058602021-09-09 20:52:45 -0500443 chassis.monitorSensors(services, *system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800444 }
445
446 // Test where devices were specified in constructor
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("vdd0",
452 "/xyz/openbmc_project/inventory/system/"
453 "chassis/motherboard/vdd0_reg",
454 defaultInventoryPath))
455 .Times(1);
456 EXPECT_CALL(sensors, startRail("vdd1",
457 "/xyz/openbmc_project/inventory/system/"
458 "chassis/motherboard/vdd1_reg",
459 defaultInventoryPath))
460 .Times(1);
461 EXPECT_CALL(sensors, setValue).Times(0);
462 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8a552922020-08-05 17:02:31 +0800463
Bob Kinga2c81a62020-07-08 13:31:16 +0800464 std::vector<std::unique_ptr<Device>> devices{};
465
Shawn McCarney17bac892021-05-08 07:55:52 -0500466 // Create Device vdd0_reg
467 {
468 // Create SensorMonitoring for Rail
Shawn McCarney83058602021-09-09 20:52:45 -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 McCarney83058602021-09-09 20:52:45 -0500473 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500474 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800475
Shawn McCarney17bac892021-05-08 07:55:52 -0500476 // Create Rail
477 std::unique_ptr<Configuration> configuration{};
Shawn McCarney83058602021-09-09 20:52:45 -0500478 auto rail = std::make_unique<Rail>("vdd0", std::move(configuration),
479 std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800480
Shawn McCarney17bac892021-05-08 07:55:52 -0500481 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -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 McCarney83058602021-09-09 20:52:45 -0500488 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500489 "vdd0_reg", true,
490 "/xyz/openbmc_project/inventory/system/chassis/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 devices.emplace_back(std::move(device));
496 }
Bob Kinga2c81a62020-07-08 13:31:16 +0800497
Shawn McCarney17bac892021-05-08 07:55:52 -0500498 // Create Device vdd1_reg
499 {
500 // Create SensorMonitoring for Rail
Shawn McCarney83058602021-09-09 20:52:45 -0500501 auto action = std::make_unique<MockAction>();
Shawn McCarney17bac892021-05-08 07:55:52 -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 McCarney83058602021-09-09 20:52:45 -0500505 auto sensorMonitoring =
Shawn McCarney17bac892021-05-08 07:55:52 -0500506 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800507
Shawn McCarney17bac892021-05-08 07:55:52 -0500508 // Create Rail
509 std::unique_ptr<Configuration> configuration{};
Shawn McCarney83058602021-09-09 20:52:45 -0500510 auto rail = std::make_unique<Rail>("vdd1", std::move(configuration),
511 std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800512
Shawn McCarney17bac892021-05-08 07:55:52 -0500513 // Create Device
Shawn McCarney83058602021-09-09 20:52:45 -0500514 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>();
Shawn McCarney17bac892021-05-08 07:55:52 -0500515 std::unique_ptr<PresenceDetection> presenceDetection{};
516 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500517 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500518 std::vector<std::unique_ptr<Rail>> rails{};
519 rails.emplace_back(std::move(rail));
Shawn McCarney83058602021-09-09 20:52:45 -0500520 auto device = std::make_unique<Device>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500521 "vdd1_reg", true,
522 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
523 "vdd1_reg",
524 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500525 std::move(deviceConfiguration), std::move(phaseFaultDetection),
526 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500527 devices.emplace_back(std::move(device));
528 }
529
530 // Create Chassis that contains Devices
Shawn McCarney83058602021-09-09 20:52:45 -0500531 Chassis chassis{2, defaultInventoryPath, std::move(devices)};
Bob Kinga2c81a62020-07-08 13:31:16 +0800532
533 // Call monitorSensors()
Shawn McCarney83058602021-09-09 20:52:45 -0500534 chassis.monitorSensors(services, *system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800535 }
536}