blob: 69968a0d5b9f1cb3937abdae02c1609cf25db5ec [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 McCarney525e20c2020-04-14 11:05:39 -050028#include "presence_detection.hpp"
29#include "rail.hpp"
30#include "rule.hpp"
Shawn McCarney17bac892021-05-08 07:55:52 -050031#include "sensor_monitoring.hpp"
Shawn McCarney2f9e14f2021-04-29 02:45:18 -050032#include "sensors.hpp"
Shawn McCarney525e20c2020-04-14 11:05:39 -050033#include "system.hpp"
Shawn McCarney9f3e54e2021-05-14 14:56:13 -050034#include "test_sdbus_error.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050035#include "test_utils.hpp"
36
37#include <memory>
38#include <stdexcept>
Shawn McCarney525e20c2020-04-14 11:05:39 -050039#include <string>
Shawn McCarney8a3afd72020-03-12 14:28:44 -050040#include <utility>
41#include <vector>
42
Bob Kinga2c81a62020-07-08 13:31:16 +080043#include <gmock/gmock.h>
Shawn McCarney8a3afd72020-03-12 14:28:44 -050044#include <gtest/gtest.h>
45
46using namespace phosphor::power::regulators;
47using namespace phosphor::power::regulators::test_utils;
48
Bob Kinga2c81a62020-07-08 13:31:16 +080049using ::testing::A;
Shawn McCarney050531f2020-06-02 14:17:12 -050050using ::testing::Return;
Shawn McCarney9f3e54e2021-05-14 14:56:13 -050051using ::testing::Throw;
Bob Kinga2c81a62020-07-08 13:31:16 +080052using ::testing::TypedEq;
Shawn McCarney050531f2020-06-02 14:17:12 -050053
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050054// Default chassis inventory path
55static const std::string defaultInventoryPath{
56 "/xyz/openbmc_project/inventory/system/chassis"};
57
Shawn McCarney8a3afd72020-03-12 14:28:44 -050058TEST(ChassisTests, Constructor)
59{
60 // Test where works: Only required parameters are specified
61 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050062 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050063 EXPECT_EQ(chassis.getNumber(), 2);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050064 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050065 EXPECT_EQ(chassis.getDevices().size(), 0);
66 }
67
68 // Test where works: All parameters are specified
69 {
70 // Create vector of Device objects
71 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050072 devices.emplace_back(createDevice("vdd_reg1"));
73 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -050074
75 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050076 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050077 EXPECT_EQ(chassis.getNumber(), 1);
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050078 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
Shawn McCarney8a3afd72020-03-12 14:28:44 -050079 EXPECT_EQ(chassis.getDevices().size(), 2);
80 }
81
82 // Test where fails: Invalid chassis number < 1
83 try
84 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -050085 Chassis chassis{0, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -050086 ADD_FAILURE() << "Should not have reached this line.";
87 }
88 catch (const std::invalid_argument& e)
89 {
90 EXPECT_STREQ(e.what(), "Invalid chassis number: 0");
91 }
92 catch (...)
93 {
94 ADD_FAILURE() << "Should not have caught exception.";
95 }
96}
97
Shawn McCarneydb0b8332020-04-06 14:13:04 -050098TEST(ChassisTests, AddToIDMap)
99{
100 // Create vector of Device objects
101 std::vector<std::unique_ptr<Device>> devices{};
102 devices.emplace_back(createDevice("reg1", {"rail1"}));
103 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
104 devices.emplace_back(createDevice("reg3"));
105
106 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500107 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500108
109 // Add Device and Rail objects within the Chassis to an IDMap
110 IDMap idMap{};
111 chassis.addToIDMap(idMap);
112
113 // Verify all Devices are in the IDMap
114 EXPECT_NO_THROW(idMap.getDevice("reg1"));
115 EXPECT_NO_THROW(idMap.getDevice("reg2"));
116 EXPECT_NO_THROW(idMap.getDevice("reg3"));
117 EXPECT_THROW(idMap.getDevice("reg4"), std::invalid_argument);
118
119 // Verify all Rails are in the IDMap
120 EXPECT_NO_THROW(idMap.getRail("rail1"));
121 EXPECT_NO_THROW(idMap.getRail("rail2a"));
122 EXPECT_NO_THROW(idMap.getRail("rail2b"));
123 EXPECT_THROW(idMap.getRail("rail3"), std::invalid_argument);
124}
125
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600126TEST(ChassisTests, ClearCache)
127{
128 // Create PresenceDetection
129 std::vector<std::unique_ptr<Action>> actions{};
130 std::unique_ptr<PresenceDetection> presenceDetection =
131 std::make_unique<PresenceDetection>(std::move(actions));
132 PresenceDetection* presenceDetectionPtr = presenceDetection.get();
133
134 // Create Device that contains PresenceDetection
135 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
136 std::unique_ptr<Device> device = std::make_unique<Device>(
137 "reg1", true,
138 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
139 std::move(i2cInterface), std::move(presenceDetection));
140 Device* devicePtr = device.get();
141
142 // Create Chassis that contains Device
143 std::vector<std::unique_ptr<Device>> devices{};
144 devices.emplace_back(std::move(device));
145 std::unique_ptr<Chassis> chassis =
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500146 std::make_unique<Chassis>(1, defaultInventoryPath, std::move(devices));
Shawn McCarney9bd94d32021-01-25 19:40:42 -0600147 Chassis* chassisPtr = chassis.get();
148
149 // Create System that contains Chassis
150 std::vector<std::unique_ptr<Rule>> rules{};
151 std::vector<std::unique_ptr<Chassis>> chassisVec{};
152 chassisVec.emplace_back(std::move(chassis));
153 System system{std::move(rules), std::move(chassisVec)};
154
155 // Cache presence value in PresenceDetection
156 MockServices services{};
157 presenceDetectionPtr->execute(services, system, *chassisPtr, *devicePtr);
158 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value());
159
160 // Clear cached data in Chassis
161 chassisPtr->clearCache();
162
163 // Verify presence value no longer cached in PresenceDetection
164 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value());
165}
166
Shawn McCarney9f3e54e2021-05-14 14:56:13 -0500167TEST(ChassisTests, ClearErrorHistory)
168{
169 // Create SensorMonitoring. Will fail with a DBus exception.
170 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
171 EXPECT_CALL(*action, execute)
172 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"}));
173 std::vector<std::unique_ptr<Action>> actions{};
174 actions.emplace_back(std::move(action));
175 std::unique_ptr<SensorMonitoring> sensorMonitoring =
176 std::make_unique<SensorMonitoring>(std::move(actions));
177
178 // Create Rail
179 std::unique_ptr<Configuration> configuration{};
180 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
181 "vddr1", std::move(configuration), std::move(sensorMonitoring));
182
183 // Create Device that contains Rail
184 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
185 std::make_unique<i2c::MockedI2CInterface>();
186 std::unique_ptr<PresenceDetection> presenceDetection{};
187 std::unique_ptr<Configuration> deviceConfiguration{};
188 std::vector<std::unique_ptr<Rail>> rails{};
189 rails.emplace_back(std::move(rail));
190 std::unique_ptr<Device> device = std::make_unique<Device>(
191 "reg1", true,
192 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
193 std::move(i2cInterface), std::move(presenceDetection),
194 std::move(deviceConfiguration), std::move(rails));
195
196 // Create Chassis that contains Device
197 std::vector<std::unique_ptr<Device>> devices{};
198 devices.emplace_back(std::move(device));
199 std::unique_ptr<Chassis> chassis =
200 std::make_unique<Chassis>(1, defaultInventoryPath, std::move(devices));
201 Chassis* chassisPtr = chassis.get();
202
203 // Create System that contains Chassis
204 std::vector<std::unique_ptr<Rule>> rules{};
205 std::vector<std::unique_ptr<Chassis>> chassisVec{};
206 chassisVec.emplace_back(std::move(chassis));
207 System system{std::move(rules), std::move(chassisVec)};
208
209 // Create mock services
210 MockServices services{};
211
212 // Expect Sensors service to be called 5+5=10 times
213 MockSensors& sensors = services.getMockSensors();
214 EXPECT_CALL(sensors, startRail).Times(10);
215 EXPECT_CALL(sensors, setValue).Times(0);
216 EXPECT_CALL(sensors, endRail).Times(10);
217
218 // Expect Journal service to be called 3+3=6 times to log error messages
219 MockJournal& journal = services.getMockJournal();
220 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>()))
221 .Times(6);
222 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6);
223
224 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error
225 MockErrorLogging& errorLogging = services.getMockErrorLogging();
226 EXPECT_CALL(errorLogging, logDBusError).Times(2);
227
228 // Monitor sensors 5 times. Should fail every time, write to journal 3
229 // times, and log one error.
230 for (int i = 1; i <= 5; ++i)
231 {
232 chassisPtr->monitorSensors(services, system);
233 }
234
235 // Clear error history
236 chassisPtr->clearErrorHistory();
237
238 // Monitor sensors 5 times again. Should fail every time, write to journal
239 // 3 times, and log one error.
240 for (int i = 1; i <= 5; ++i)
241 {
242 chassisPtr->monitorSensors(services, system);
243 }
244}
245
Shawn McCarney050531f2020-06-02 14:17:12 -0500246TEST(ChassisTests, CloseDevices)
247{
248 // Test where no devices were specified in constructor
249 {
Bob Kingd692d6d2020-09-14 13:42:57 +0800250 // Create mock services. Expect logDebug() to be called.
251 MockServices services{};
252 MockJournal& journal = services.getMockJournal();
253 EXPECT_CALL(journal, logDebug("Closing devices in chassis 2")).Times(1);
254
Shawn McCarney050531f2020-06-02 14:17:12 -0500255 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500256 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney050531f2020-06-02 14:17:12 -0500257
258 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800259 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500260 }
261
262 // Test where devices were specified in constructor
263 {
264 std::vector<std::unique_ptr<Device>> devices{};
265
Bob Kingd692d6d2020-09-14 13:42:57 +0800266 // Create mock services. Expect logDebug() to be called.
267 MockServices services{};
268 MockJournal& journal = services.getMockJournal();
269 EXPECT_CALL(journal, logDebug("Closing devices in chassis 1")).Times(1);
270
Shawn McCarney050531f2020-06-02 14:17:12 -0500271 // Create Device vdd0_reg
272 {
273 // Create mock I2CInterface: isOpen() and close() should be called
274 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
275 std::make_unique<i2c::MockedI2CInterface>();
276 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
277 EXPECT_CALL(*i2cInterface, close).Times(1);
278
279 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800280 std::unique_ptr<Device> device =
281 std::make_unique<Device>("vdd0_reg", true,
282 "/xyz/openbmc_project/inventory/"
283 "system/chassis/motherboard/vdd0_reg",
284 std::move(i2cInterface));
Shawn McCarney050531f2020-06-02 14:17:12 -0500285 devices.emplace_back(std::move(device));
286 }
287
288 // Create Device vdd1_reg
289 {
290 // Create mock I2CInterface: isOpen() and close() should be called
291 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
292 std::make_unique<i2c::MockedI2CInterface>();
293 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
294 EXPECT_CALL(*i2cInterface, close).Times(1);
295
296 // Create Device
Bob Kinga76898f2020-10-13 15:08:33 +0800297 std::unique_ptr<Device> device =
298 std::make_unique<Device>("vdd1_reg", true,
299 "/xyz/openbmc_project/inventory/"
300 "system/chassis/motherboard/vdd1_reg",
301 std::move(i2cInterface));
Shawn McCarney050531f2020-06-02 14:17:12 -0500302 devices.emplace_back(std::move(device));
303 }
304
305 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500306 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney050531f2020-06-02 14:17:12 -0500307
308 // Call closeDevices()
Bob Kingd692d6d2020-09-14 13:42:57 +0800309 chassis.closeDevices(services);
Shawn McCarney050531f2020-06-02 14:17:12 -0500310 }
311}
312
Shawn McCarney525e20c2020-04-14 11:05:39 -0500313TEST(ChassisTests, Configure)
314{
315 // Test where no devices were specified in constructor
316 {
Bob King5cfe5102020-07-30 16:26:18 +0800317 // Create mock services. Expect logInfo() to be called.
Bob King23243f82020-07-29 10:38:57 +0800318 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800319 MockJournal& journal = services.getMockJournal();
320 EXPECT_CALL(journal, logInfo("Configuring chassis 1")).Times(1);
321 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
322 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800323
Shawn McCarney525e20c2020-04-14 11:05:39 -0500324 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500325 std::unique_ptr<Chassis> chassis =
326 std::make_unique<Chassis>(1, defaultInventoryPath);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500327 Chassis* chassisPtr = chassis.get();
328
329 // Create System that contains Chassis
330 std::vector<std::unique_ptr<Rule>> rules{};
331 std::vector<std::unique_ptr<Chassis>> chassisVec{};
332 chassisVec.emplace_back(std::move(chassis));
333 System system{std::move(rules), std::move(chassisVec)};
334
335 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800336 chassisPtr->configure(services, system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500337 }
338
339 // Test where devices were specified in constructor
340 {
341 std::vector<std::unique_ptr<Device>> devices{};
342
Bob King5cfe5102020-07-30 16:26:18 +0800343 // Create mock services. Expect logInfo() and logDebug() to be called.
344 MockServices services{};
345 MockJournal& journal = services.getMockJournal();
346 EXPECT_CALL(journal, logInfo("Configuring chassis 2")).Times(1);
347 EXPECT_CALL(journal, logDebug("Configuring vdd0_reg: volts=1.300000"))
348 .Times(1);
349 EXPECT_CALL(journal, logDebug("Configuring vdd1_reg: volts=1.200000"))
350 .Times(1);
351 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
352
Shawn McCarney525e20c2020-04-14 11:05:39 -0500353 // Create Device vdd0_reg
354 {
355 // Create Configuration
356 std::vector<std::unique_ptr<Action>> actions{};
357 std::unique_ptr<Configuration> configuration =
358 std::make_unique<Configuration>(1.3, std::move(actions));
359
360 // Create Device
361 std::unique_ptr<i2c::I2CInterface> i2cInterface =
362 createI2CInterface();
363 std::unique_ptr<PresenceDetection> presenceDetection{};
364 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800365 "vdd0_reg", true,
366 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
367 "vdd0_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500368 std::move(i2cInterface), std::move(presenceDetection),
369 std::move(configuration));
370 devices.emplace_back(std::move(device));
371 }
372
373 // Create Device vdd1_reg
374 {
375 // Create Configuration
376 std::vector<std::unique_ptr<Action>> actions{};
377 std::unique_ptr<Configuration> configuration =
378 std::make_unique<Configuration>(1.2, std::move(actions));
379
380 // Create Device
381 std::unique_ptr<i2c::I2CInterface> i2cInterface =
382 createI2CInterface();
383 std::unique_ptr<PresenceDetection> presenceDetection{};
384 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800385 "vdd1_reg", true,
386 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
387 "vdd1_reg",
Shawn McCarney525e20c2020-04-14 11:05:39 -0500388 std::move(i2cInterface), std::move(presenceDetection),
389 std::move(configuration));
390 devices.emplace_back(std::move(device));
391 }
392
393 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500394 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
395 2, defaultInventoryPath, std::move(devices));
Shawn McCarney525e20c2020-04-14 11:05:39 -0500396 Chassis* chassisPtr = chassis.get();
397
398 // Create System that contains Chassis
399 std::vector<std::unique_ptr<Rule>> rules{};
400 std::vector<std::unique_ptr<Chassis>> chassisVec{};
401 chassisVec.emplace_back(std::move(chassis));
402 System system{std::move(rules), std::move(chassisVec)};
403
404 // Call configure()
Bob King23243f82020-07-29 10:38:57 +0800405 chassisPtr->configure(services, system);
Shawn McCarney525e20c2020-04-14 11:05:39 -0500406 }
407}
408
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500409TEST(ChassisTests, GetDevices)
410{
411 // Test where no devices were specified in constructor
412 {
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500413 Chassis chassis{2, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500414 EXPECT_EQ(chassis.getDevices().size(), 0);
415 }
416
417 // Test where devices were specified in constructor
418 {
419 // Create vector of Device objects
420 std::vector<std::unique_ptr<Device>> devices{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500421 devices.emplace_back(createDevice("vdd_reg1"));
422 devices.emplace_back(createDevice("vdd_reg2"));
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500423
424 // Create Chassis
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500425 Chassis chassis{1, defaultInventoryPath, std::move(devices)};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500426 EXPECT_EQ(chassis.getDevices().size(), 2);
427 EXPECT_EQ(chassis.getDevices()[0]->getID(), "vdd_reg1");
428 EXPECT_EQ(chassis.getDevices()[1]->getID(), "vdd_reg2");
429 }
430}
431
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500432TEST(ChassisTests, GetInventoryPath)
433{
434 Chassis chassis{3, defaultInventoryPath};
435 EXPECT_EQ(chassis.getInventoryPath(), defaultInventoryPath);
436}
437
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500438TEST(ChassisTests, GetNumber)
439{
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500440 Chassis chassis{3, defaultInventoryPath};
Shawn McCarney8a3afd72020-03-12 14:28:44 -0500441 EXPECT_EQ(chassis.getNumber(), 3);
442}
Bob Kinga2c81a62020-07-08 13:31:16 +0800443
444TEST(ChassisTests, MonitorSensors)
445{
446 // Test where no devices were specified in constructor
447 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500448 // Create mock services. No Sensors methods should be called.
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).Times(0);
452 EXPECT_CALL(sensors, setValue).Times(0);
453 EXPECT_CALL(sensors, endRail).Times(0);
Bob King8a552922020-08-05 17:02:31 +0800454
Bob Kinga2c81a62020-07-08 13:31:16 +0800455 // Create Chassis
Shawn McCarney17bac892021-05-08 07:55:52 -0500456 std::unique_ptr<Chassis> chassis =
457 std::make_unique<Chassis>(1, defaultInventoryPath);
Bob Kinga2c81a62020-07-08 13:31:16 +0800458 Chassis* chassisPtr = chassis.get();
459
460 // Create System that contains Chassis
461 std::vector<std::unique_ptr<Rule>> rules{};
462 std::vector<std::unique_ptr<Chassis>> chassisVec{};
463 chassisVec.emplace_back(std::move(chassis));
464 System system{std::move(rules), std::move(chassisVec)};
465
466 // Call monitorSensors(). Should do nothing.
Bob King8a552922020-08-05 17:02:31 +0800467 chassisPtr->monitorSensors(services, system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800468 }
469
470 // Test where devices were specified in constructor
471 {
Shawn McCarney17bac892021-05-08 07:55:52 -0500472 // Create mock services. Set Sensors service expectations.
Bob King8a552922020-08-05 17:02:31 +0800473 MockServices services{};
Shawn McCarney17bac892021-05-08 07:55:52 -0500474 MockSensors& sensors = services.getMockSensors();
475 EXPECT_CALL(sensors, startRail("vdd0",
476 "/xyz/openbmc_project/inventory/system/"
477 "chassis/motherboard/vdd0_reg",
478 defaultInventoryPath))
479 .Times(1);
480 EXPECT_CALL(sensors, startRail("vdd1",
481 "/xyz/openbmc_project/inventory/system/"
482 "chassis/motherboard/vdd1_reg",
483 defaultInventoryPath))
484 .Times(1);
485 EXPECT_CALL(sensors, setValue).Times(0);
486 EXPECT_CALL(sensors, endRail(false)).Times(2);
Bob King8a552922020-08-05 17:02:31 +0800487
Bob Kinga2c81a62020-07-08 13:31:16 +0800488 std::vector<std::unique_ptr<Device>> devices{};
489
Shawn McCarney17bac892021-05-08 07:55:52 -0500490 // Create Device vdd0_reg
491 {
492 // Create SensorMonitoring for Rail
493 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
494 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
495 std::vector<std::unique_ptr<Action>> actions{};
496 actions.emplace_back(std::move(action));
497 std::unique_ptr<SensorMonitoring> sensorMonitoring =
498 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800499
Shawn McCarney17bac892021-05-08 07:55:52 -0500500 // Create Rail
501 std::unique_ptr<Configuration> configuration{};
502 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
503 "vdd0", std::move(configuration), std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800504
Shawn McCarney17bac892021-05-08 07:55:52 -0500505 // Create Device
506 std::unique_ptr<i2c::I2CInterface> i2cInterface =
507 createI2CInterface();
508 std::unique_ptr<PresenceDetection> presenceDetection{};
509 std::unique_ptr<Configuration> deviceConfiguration{};
510 std::vector<std::unique_ptr<Rail>> rails{};
511 rails.emplace_back(std::move(rail));
512 std::unique_ptr<Device> device = std::make_unique<Device>(
513 "vdd0_reg", true,
514 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
515 "vdd0_reg",
516 std::move(i2cInterface), std::move(presenceDetection),
517 std::move(deviceConfiguration), std::move(rails));
518 devices.emplace_back(std::move(device));
519 }
Bob Kinga2c81a62020-07-08 13:31:16 +0800520
Shawn McCarney17bac892021-05-08 07:55:52 -0500521 // Create Device vdd1_reg
522 {
523 // Create SensorMonitoring for Rail
524 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
525 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
526 std::vector<std::unique_ptr<Action>> actions{};
527 actions.emplace_back(std::move(action));
528 std::unique_ptr<SensorMonitoring> sensorMonitoring =
529 std::make_unique<SensorMonitoring>(std::move(actions));
Bob Kinga2c81a62020-07-08 13:31:16 +0800530
Shawn McCarney17bac892021-05-08 07:55:52 -0500531 // Create Rail
532 std::unique_ptr<Configuration> configuration{};
533 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
534 "vdd1", std::move(configuration), std::move(sensorMonitoring));
Bob Kinga2c81a62020-07-08 13:31:16 +0800535
Shawn McCarney17bac892021-05-08 07:55:52 -0500536 // Create Device
537 std::unique_ptr<i2c::I2CInterface> i2cInterface =
538 createI2CInterface();
539 std::unique_ptr<PresenceDetection> presenceDetection{};
540 std::unique_ptr<Configuration> deviceConfiguration{};
541 std::vector<std::unique_ptr<Rail>> rails{};
542 rails.emplace_back(std::move(rail));
543 std::unique_ptr<Device> device = std::make_unique<Device>(
544 "vdd1_reg", true,
545 "/xyz/openbmc_project/inventory/system/chassis/motherboard/"
546 "vdd1_reg",
547 std::move(i2cInterface), std::move(presenceDetection),
548 std::move(deviceConfiguration), std::move(rails));
549 devices.emplace_back(std::move(device));
550 }
551
552 // Create Chassis that contains Devices
Shawn McCarneycb3f6a62021-04-30 10:54:30 -0500553 std::unique_ptr<Chassis> chassis = std::make_unique<Chassis>(
Shawn McCarney17bac892021-05-08 07:55:52 -0500554 2, defaultInventoryPath, std::move(devices));
Bob Kinga2c81a62020-07-08 13:31:16 +0800555 Chassis* chassisPtr = chassis.get();
556
557 // Create System that contains Chassis
558 std::vector<std::unique_ptr<Rule>> rules{};
559 std::vector<std::unique_ptr<Chassis>> chassisVec{};
560 chassisVec.emplace_back(std::move(chassis));
561 System system{std::move(rules), std::move(chassisVec)};
562
563 // Call monitorSensors()
Bob King8a552922020-08-05 17:02:31 +0800564 chassisPtr->monitorSensors(services, system);
Bob Kinga2c81a62020-07-08 13:31:16 +0800565 }
566}