blob: 72d15943575d8fb8f8ce28f37ae9f4354da2cdbd [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 McCarneycb3f6a62021-04-30 10:54:30 -050055// Default chassis inventory path
56static const std::string defaultInventoryPath{
57 "/xyz/openbmc_project/inventory/system/chassis"};
58
Shawn McCarney8a3afd72020-03-12 14:28:44 -050059TEST(ChassisTests, Constructor)
60{
61 // Test where works: Only required parameters are specified
62 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050063 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050064 EXPECT_EQ(chassis.getNumber(), 2);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050065 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050066 EXPECT_EQ(chassis.getDevices().size(), 0);
67 }
68
69 // Test where works: All parameters are specified
70 {
71 // Create vector of Device objects
72 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050073 devices.emplace_back(createDevice("vdd_reg1"));
74 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -050075
76 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050077 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050078 EXPECT_EQ(chassis.getNumber(), 1);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050079 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050080 EXPECT_EQ(chassis.getDevices().size(), 2);
81 }
82
83 // Test where fails: Invalid chassis number < 1
84 try
85 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050086 Chassis chassis{0, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050087 ADD_FAILURE() << "Should not have reached this line.";
88 }
89 catch (const std::invalid_argument& e)
90 {
91 EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
92 }
93 catch (...)
94 {
95 ADD_FAILURE() << "Should not have caught exception.";
96 }
97}
98
Shawn McCarneydb0b8332020-04-06 14:13:04 -050099TEST(ChassisTests, AddToIDMap)
100{
101 // Create vector of Device objects
102 std::vector<std::unique_ptr<Device>> devices{};
103 devices.emplace_back(createDevice("reg1", {"rail1"}));
104 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
105 devices.emplace_back(createDevice("reg3"));
106
107 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500108 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500109
110 // Add Device and Rail objects within the Chassis to an IDMap
111 IDMap idMap{};
112 chassis.addToIDMap(idMap);
113
114 // Verify all Devices are in the IDMap
115 EXPECT_NO_THROW(idMap.getDevice("reg1"));
116 EXPECT_NO_THROW(idMap.getDevice("reg2"));
117 EXPECT_NO_THROW(idMap.getDevice("reg3"));
118 EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
119
120 // Verify all Rails are in the IDMap
121 EXPECT_NO_THROW(idMap.getRail("rail1"));
122 EXPECT_NO_THROW(idMap.getRail("rail2a"));
123 EXPECT_NO_THROW(idMap.getRail("rail2b"));
124 EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
125}
126
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600127TEST(ChassisTests, ClearCache)
128{
129 // Create PresenceDetection
130 std::vector<std::unique_ptr<Action>> actions{};
131 std::unique_ptr<PresenceDetection> presenceDetection =
132 std::make_unique<PresenceDetection>(std::move(actions));
133 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
134
135 // Create Device that contains PresenceDetection
136 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
137 std::unique_ptr<Device> device = std::make_unique<Device>(
138 "reg1", true,
139 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
140 std::move(i2cInterface), std::move(presenceDetection));
141 Device* devicePtr = device.get();
142
143 // Create Chassis that contains Device
144 std::vector<std::unique_ptr<Device>> devices{};
145 devices.emplace_back(std::move(device));
146 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500147 std::make_unique<Chassis>(1, defaultInventoryPath, std::move(devices));
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600148 Chassis* chassisPtr = chassis.get();
149
150 // Create System that contains Chassis
151 std::vector<std::unique_ptr<Rule>> rules{};
152 std::vector<std::unique_ptr<Chassis>> chassisVec{};
153 chassisVec.emplace_back(std::move(chassis));
154 System system{std::move(rules), std::move(chassisVec)};
155
156 // Cache presence value in PresenceDetection
157 MockServices services{};
158 presenceDetectionPtr->execute(services, system, *chassisPtr, *devicePtr);
159 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
160
161 // Clear cached data in Chassis
162 chassisPtr->clearCache();
163
164 // Verify presence value no longer cached in PresenceDetection
165 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
166}
167
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500168TEST(ChassisTests, ClearErrorHistory)
169{
170 // Create SensorMonitoring. Will fail with a DBus exception.
171 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
172 EXPECT_CALL(*action, execute)
173 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
174 std::vector<std::unique_ptr<Action>> actions{};
175 actions.emplace_back(std::move(action));
176 std::unique_ptr<SensorMonitoring> sensorMonitoring =
177 std::make_unique<SensorMonitoring>(std::move(actions));
178
179 // Create Rail
180 std::unique_ptr<Configuration> configuration{};
181 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
182 "vddr1", std::move(configuration), std::move(sensorMonitoring));
183
184 // Create Device that contains Rail
185 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
186 std::make_unique<i2c::MockedI2CInterface>();
187 std::unique_ptr<PresenceDetection> presenceDetection{};
188 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500189 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500190 std::vector<std::unique_ptr<Rail>> rails{};
191 rails.emplace_back(std::move(rail));
192 std::unique_ptr<Device> device = std::make_unique<Device>(
193 "reg1", true,
194 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
195 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500196 std::move(deviceConfiguration), std::move(phaseFaultDetection),
197 std::move(rails));
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500198
199 // Create Chassis that contains Device
200 std::vector<std::unique_ptr<Device>> devices{};
201 devices.emplace_back(std::move(device));
202 std::unique_ptr<Chassis> chassis =
203 std::make_unique<Chassis>(1, defaultInventoryPath, std::move(devices));
204 Chassis* chassisPtr = chassis.get();
205
206 // Create System that contains Chassis
207 std::vector<std::unique_ptr<Rule>> rules{};
208 std::vector<std::unique_ptr<Chassis>> chassisVec{};
209 chassisVec.emplace_back(std::move(chassis));
210 System system{std::move(rules), std::move(chassisVec)};
211
212 // Create mock services
213 MockServices services{};
214
215 // Expect Sensors service to be called 5+5=10 times
216 MockSensors& sensors = services.getMockSensors();
217 EXPECT_CALL(sensors, startRail).Times(10);
218 EXPECT_CALL(sensors, setValue).Times(0);
219 EXPECT_CALL(sensors, endRail).Times(10);
220
221 // Expect Journal service to be called 3+3=6 times to log error messages
222 MockJournal& journal = services.getMockJournal();
223 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
224 .Times(6);
225 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
226
227 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
228 MockErrorLogging& errorLogging = services.getMockErrorLogging();
229 EXPECT_CALL(errorLogging, logDBusError).Times(2);
230
231 // Monitor sensors 5 times. Should fail every time, write to journal 3
232 // times, and log one error.
233 for (int i = 1; i <= 5; ++i)
234 {
235 chassisPtr->monitorSensors(services, system);
236 }
237
238 // Clear error history
239 chassisPtr->clearErrorHistory();
240
241 // Monitor sensors 5 times again. Should fail every time, write to journal
242 // 3 times, and log one error.
243 for (int i = 1; i <= 5; ++i)
244 {
245 chassisPtr->monitorSensors(services, system);
246 }
247}
248
Shawn McCarney050531f2020-06-02 14:17:12 -0500249TEST(ChassisTests, CloseDevices)
250{
251 // Test where no devices were specified in constructor
252 {
Bob Kingd692d6d2020-09-14 13:42:57 +0800253 // Create mock services. Expect logDebug() to be called.
254 MockServices services{};
255 MockJournal& journal = services.getMockJournal();
256 EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1);
257
Shawn McCarney050531f2020-06-02 14:17:12 -0500258 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500259 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney050531f2020-06-02 14:17:12 -0500260
261 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800262 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500263 }
264
265 // Test where devices were specified in constructor
266 {
267 std::vector<std::unique_ptr<Device>> devices{};
268
Bob Kingd692d6d2020-09-14 13:42:57 +0800269 // Create mock services. Expect logDebug() to be called.
270 MockServices services{};
271 MockJournal& journal = services.getMockJournal();
272 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
273
Shawn McCarney050531f2020-06-02 14:17:12 -0500274 // Create Device vdd0_reg
275 {
276 // Create mock I2CInterface: isOpen() and close() should be called
277 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
278 std::make_unique<i2c::MockedI2CInterface>();
279 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
280 EXPECT_CALL(*i2cInterface, close).Times(1);
281
282 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800283 std::unique_ptr<Device> device =
284 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
294 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
295 std::make_unique<i2c::MockedI2CInterface>();
296 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
297 EXPECT_CALL(*i2cInterface, close).Times(1);
298
299 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800300 std::unique_ptr<Device> device =
301 std::make_unique<Device>("vdd1_reg", true,
302 "/xyz/openbmc_project/inventory/"
303 "system/chassis/motherboard/vdd1_reg",
304 std::move(i2cInterface));
Shawn McCarney050531f2020-06-02 14:17:12 -0500305 devices.emplace_back(std::move(device));
306 }
307
308 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500309 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney050531f2020-06-02 14:17:12 -0500310
311 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800312 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500313 }
314}
315
Shawn McCarney525e20c2020-04-14 11:05:39 -0500316TEST(ChassisTests, Configure)
317{
318 // Test where no devices were specified in constructor
319 {
Bob King5cfe5102020-07-30 16:26:18 +0800320 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800321 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800322 MockJournal& journal = services.getMockJournal();
323 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
324 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
325 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800326
Shawn McCarney525e20c2020-04-14 11:05:39 -0500327 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500328 std::unique_ptr<Chassis> chassis =
329 std::make_unique<Chassis>(1, defaultInventoryPath);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500330 Chassis* chassisPtr = chassis.get();
331
332 // Create System that contains Chassis
333 std::vector<std::unique_ptr<Rule>> rules{};
334 std::vector<std::unique_ptr<Chassis>> chassisVec{};
335 chassisVec.emplace_back(std::move(chassis));
336 System system{std::move(rules), std::move(chassisVec)};
337
338 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800339 chassisPtr->configure(services, system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500340 }
341
342 // Test where devices were specified in constructor
343 {
344 std::vector<std::unique_ptr<Device>> devices{};
345
Bob King5cfe5102020-07-30 16:26:18 +0800346 // Create mock services. Expect logInfo() and logDebug() to be called.
347 MockServices services{};
348 MockJournal& journal = services.getMockJournal();
349 EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1);
350 EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000"))
351 .Times(1);
352 EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000"))
353 .Times(1);
354 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
355
Shawn McCarney525e20c2020-04-14 11:05:39 -0500356 // Create Device vdd0_reg
357 {
358 // Create Configuration
359 std::vector<std::unique_ptr<Action>> actions{};
360 std::unique_ptr<Configuration> configuration =
361 std::make_unique<Configuration>(1.3, std::move(actions));
362
363 // Create Device
364 std::unique_ptr<i2c::I2CInterface> i2cInterface =
365 createI2CInterface();
366 std::unique_ptr<PresenceDetection> presenceDetection{};
367 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800368 "vdd0_reg", true,
369 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
370 "vdd0_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500371 std::move(i2cInterface), std::move(presenceDetection),
372 std::move(configuration));
373 devices.emplace_back(std::move(device));
374 }
375
376 // Create Device vdd1_reg
377 {
378 // Create Configuration
379 std::vector<std::unique_ptr<Action>> actions{};
380 std::unique_ptr<Configuration> configuration =
381 std::make_unique<Configuration>(1.2, std::move(actions));
382
383 // Create Device
384 std::unique_ptr<i2c::I2CInterface> i2cInterface =
385 createI2CInterface();
386 std::unique_ptr<PresenceDetection> presenceDetection{};
387 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800388 "vdd1_reg", true,
389 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
390 "vdd1_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500391 std::move(i2cInterface), std::move(presenceDetection),
392 std::move(configuration));
393 devices.emplace_back(std::move(device));
394 }
395
396 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500397 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
398 2, defaultInventoryPath, std::move(devices));
Shawn McCarney525e20c2020-04-14 11:05:39 -0500399 Chassis* chassisPtr = chassis.get();
400
401 // Create System that contains Chassis
402 std::vector<std::unique_ptr<Rule>> rules{};
403 std::vector<std::unique_ptr<Chassis>> chassisVec{};
404 chassisVec.emplace_back(std::move(chassis));
405 System system{std::move(rules), std::move(chassisVec)};
406
407 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800408 chassisPtr->configure(services, system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500409 }
410}
411
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500412TEST(ChassisTests, GetDevices)
413{
414 // Test where no devices were specified in constructor
415 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500416 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500417 EXPECT_EQ(chassis.getDevices().size(), 0);
418 }
419
420 // Test where devices were specified in constructor
421 {
422 // Create vector of Device objects
423 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500424 devices.emplace_back(createDevice("vdd_reg1"));
425 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500426
427 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500428 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500429 EXPECT_EQ(chassis.getDevices().size(), 2);
430 EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
431 EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
432 }
433}
434
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500435TEST(ChassisTests, GetInventoryPath)
436{
437 Chassis chassis{3, defaultInventoryPath};
438 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
439}
440
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500441TEST(ChassisTests, GetNumber)
442{
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500443 Chassis chassis{3, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500444 EXPECT_EQ(chassis.getNumber(), 3);
445}
Bob Kinga2c81a62020-07-08 13:31:16 +0800446
447TEST(ChassisTests, MonitorSensors)
448{
449 // Test where no devices were specified in constructor
450 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500451 // Create mock services. No Sensors methods should be called.
Bob King8a552922020-08-05 17:02:31 +0800452 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500453 MockSensors& sensors = services.getMockSensors();
454 EXPECT_CALL(sensors, startRail).Times(0);
455 EXPECT_CALL(sensors, setValue).Times(0);
456 EXPECT_CALL(sensors, endRail).Times(0);
Bob King8a552922020-08-05 17:02:31 +0800457
Bob Kinga2c81a62020-07-08 13:31:16 +0800458 // Create Chassis
Shawn McCarney17bac892021-05-08 07:55:52 -0500459 std::unique_ptr<Chassis> chassis =
460 std::make_unique<Chassis>(1, defaultInventoryPath);
Bob Kinga2c81a62020-07-08 13:31:16 +0800461 Chassis* chassisPtr = chassis.get();
462
463 // Create System that contains Chassis
464 std::vector<std::unique_ptr<Rule>> rules{};
465 std::vector<std::unique_ptr<Chassis>> chassisVec{};
466 chassisVec.emplace_back(std::move(chassis));
467 System system{std::move(rules), std::move(chassisVec)};
468
469 // Call monitorSensors(). Should do nothing.
Bob King8a552922020-08-05 17:02:31 +0800470 chassisPtr->monitorSensors(services, system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800471 }
472
473 // Test where devices were specified in constructor
474 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500475 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800476 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500477 MockSensors& sensors = services.getMockSensors();
478 EXPECT_CALL(sensors, startRail("vdd0",
479 "/xyz/openbmc_project/inventory/system/"
480 "chassis/motherboard/vdd0_reg",
481 defaultInventoryPath))
482 .Times(1);
483 EXPECT_CALL(sensors, startRail("vdd1",
484 "/xyz/openbmc_project/inventory/system/"
485 "chassis/motherboard/vdd1_reg",
486 defaultInventoryPath))
487 .Times(1);
488 EXPECT_CALL(sensors, setValue).Times(0);
489 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8a552922020-08-05 17:02:31 +0800490
Bob Kinga2c81a62020-07-08 13:31:16 +0800491 std::vector<std::unique_ptr<Device>> devices{};
492
Shawn McCarney17bac892021-05-08 07:55:52 -0500493 // Create Device vdd0_reg
494 {
495 // Create SensorMonitoring for Rail
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<SensorMonitoring> sensorMonitoring =
501 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800502
Shawn McCarney17bac892021-05-08 07:55:52 -0500503 // Create Rail
504 std::unique_ptr<Configuration> configuration{};
505 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
506 "vdd0", std::move(configuration), std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800507
Shawn McCarney17bac892021-05-08 07:55:52 -0500508 // Create Device
509 std::unique_ptr<i2c::I2CInterface> i2cInterface =
510 createI2CInterface();
511 std::unique_ptr<PresenceDetection> presenceDetection{};
512 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500513 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500514 std::vector<std::unique_ptr<Rail>> rails{};
515 rails.emplace_back(std::move(rail));
516 std::unique_ptr<Device> device = std::make_unique<Device>(
517 "vdd0_reg", true,
518 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
519 "vdd0_reg",
520 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500521 std::move(deviceConfiguration), std::move(phaseFaultDetection),
522 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500523 devices.emplace_back(std::move(device));
524 }
Bob Kinga2c81a62020-07-08 13:31:16 +0800525
Shawn McCarney17bac892021-05-08 07:55:52 -0500526 // Create Device vdd1_reg
527 {
528 // Create SensorMonitoring for Rail
529 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
530 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
531 std::vector<std::unique_ptr<Action>> actions{};
532 actions.emplace_back(std::move(action));
533 std::unique_ptr<SensorMonitoring> sensorMonitoring =
534 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800535
Shawn McCarney17bac892021-05-08 07:55:52 -0500536 // Create Rail
537 std::unique_ptr<Configuration> configuration{};
538 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
539 "vdd1", std::move(configuration), std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800540
Shawn McCarney17bac892021-05-08 07:55:52 -0500541 // Create Device
542 std::unique_ptr<i2c::I2CInterface> i2cInterface =
543 createI2CInterface();
544 std::unique_ptr<PresenceDetection> presenceDetection{};
545 std::unique_ptr<Configuration> deviceConfiguration{};
Shawn McCarney32252592021-09-08 15:29:36 -0500546 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500547 std::vector<std::unique_ptr<Rail>> rails{};
548 rails.emplace_back(std::move(rail));
549 std::unique_ptr<Device> device = std::make_unique<Device>(
550 "vdd1_reg", true,
551 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
552 "vdd1_reg",
553 std::move(i2cInterface), std::move(presenceDetection),
Shawn McCarney32252592021-09-08 15:29:36 -0500554 std::move(deviceConfiguration), std::move(phaseFaultDetection),
555 std::move(rails));
Shawn McCarney17bac892021-05-08 07:55:52 -0500556 devices.emplace_back(std::move(device));
557 }
558
559 // Create Chassis that contains Devices
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500560 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500561 2, defaultInventoryPath, std::move(devices));
Bob Kinga2c81a62020-07-08 13:31:16 +0800562 Chassis* chassisPtr = chassis.get();
563
564 // Create System that contains Chassis
565 std::vector<std::unique_ptr<Rule>> rules{};
566 std::vector<std::unique_ptr<Chassis>> chassisVec{};
567 chassisVec.emplace_back(std::move(chassis));
568 System system{std::move(rules), std::move(chassisVec)};
569
570 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800571 chassisPtr->monitorSensors(services, system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800572 }
573}