blob: 62cf97e5d98ec9b74c5265086e09bcd9cbb76510 [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 McCarneyeb7bec42020-04-14 09:38:15 -050022#include "journal.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050023#include "mock_action.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050024#include "mock_journal.hpp"
Bob King23243f82020-07-29 10:38:57 +080025#include "mock_services.hpp"
Shawn McCarneyb4d18a42020-06-02 10:27:05 -050026#include "mocked_i2c_interface.hpp"
Bob King8e1cd0b2020-07-08 13:30:27 +080027#include "pmbus_read_sensor_action.hpp"
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050028#include "presence_detection.hpp"
29#include "rail.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050030#include "rule.hpp"
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050031#include "system.hpp"
Shawn McCarney8a3afd72020-03-12 14:28:44 -050032#include "test_utils.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060033
34#include <memory>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050035#include <optional>
Shawn McCarney525e20c2020-04-14 11:05:39 -050036#include <string>
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060037#include <utility>
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050038#include <vector>
Shawn McCarneya2461b32019-10-24 18:53:01 -050039
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050040#include <gmock/gmock.h>
Shawn McCarneya2461b32019-10-24 18:53:01 -050041#include <gtest/gtest.h>
42
43using namespace phosphor::power::regulators;
Shawn McCarney8a3afd72020-03-12 14:28:44 -050044using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060045
Bob King8e1cd0b2020-07-08 13:30:27 +080046using ::testing::A;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050047using ::testing::Return;
Shawn McCarneyb4d18a42020-06-02 10:27:05 -050048using ::testing::Throw;
Bob King8e1cd0b2020-07-08 13:30:27 +080049using ::testing::TypedEq;
Shawn McCarneyeb7bec42020-04-14 09:38:15 -050050
Shawn McCarneya2461b32019-10-24 18:53:01 -050051TEST(DeviceTests, Constructor)
52{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -050053 // Test where only required parameters are specified
54 {
55 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
56 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
57 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
58 std::move(i2cInterface)};
59 EXPECT_EQ(device.getID(), "vdd_reg");
60 EXPECT_EQ(device.isRegulator(), true);
61 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg2");
62 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
63 EXPECT_EQ(device.getPresenceDetection(), nullptr);
64 EXPECT_EQ(device.getConfiguration(), nullptr);
65 EXPECT_EQ(device.getRails().size(), 0);
66 }
67
68 // Test where all parameters are specified
69 {
70 // Create I2CInterface
71 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
72 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
73
74 // Create PresenceDetection
75 std::vector<std::unique_ptr<Action>> actions{};
76 actions.push_back(std::make_unique<MockAction>());
77 std::unique_ptr<PresenceDetection> presenceDetection =
78 std::make_unique<PresenceDetection>(std::move(actions));
79
80 // Create Configuration
81 std::optional<double> volts{};
82 actions.clear();
83 actions.push_back(std::make_unique<MockAction>());
84 actions.push_back(std::make_unique<MockAction>());
85 std::unique_ptr<Configuration> configuration =
86 std::make_unique<Configuration>(volts, std::move(actions));
87
88 // Create vector of Rail objects
89 std::vector<std::unique_ptr<Rail>> rails{};
90 rails.push_back(std::make_unique<Rail>("vdd0"));
91 rails.push_back(std::make_unique<Rail>("vdd1"));
92
93 // Create Device
94 Device device{"vdd_reg",
95 false,
96 "/system/chassis/motherboard/reg1",
97 std::move(i2cInterface),
98 std::move(presenceDetection),
99 std::move(configuration),
100 std::move(rails)};
101 EXPECT_EQ(device.getID(), "vdd_reg");
102 EXPECT_EQ(device.isRegulator(), false);
103 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg1");
104 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
105 EXPECT_NE(device.getPresenceDetection(), nullptr);
106 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
107 EXPECT_NE(device.getConfiguration(), nullptr);
108 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), false);
109 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
110 EXPECT_EQ(device.getRails().size(), 2);
111 }
Shawn McCarneya2461b32019-10-24 18:53:01 -0500112}
113
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500114TEST(DeviceTests, AddToIDMap)
115{
116 std::unique_ptr<PresenceDetection> presenceDetection{};
117 std::unique_ptr<Configuration> configuration{};
118
119 // Create vector of Rail objects
120 std::vector<std::unique_ptr<Rail>> rails{};
121 rails.push_back(std::make_unique<Rail>("vdd0"));
122 rails.push_back(std::make_unique<Rail>("vdd1"));
123
124 // Create Device
125 Device device{"vdd_reg",
126 false,
127 "/system/chassis/motherboard/reg2",
128 std::move(createI2CInterface()),
129 std::move(presenceDetection),
130 std::move(configuration),
131 std::move(rails)};
132
133 // Add Device and Rail objects to an IDMap
134 IDMap idMap{};
135 device.addToIDMap(idMap);
136
137 // Verify Device is in the IDMap
138 EXPECT_NO_THROW(idMap.getDevice("vdd_reg"));
139 EXPECT_THROW(idMap.getDevice("vio_reg"), std::invalid_argument);
140
141 // Verify all Rails are in the IDMap
142 EXPECT_NO_THROW(idMap.getRail("vdd0"));
143 EXPECT_NO_THROW(idMap.getRail("vdd1"));
144 EXPECT_THROW(idMap.getRail("vdd2"), std::invalid_argument);
145}
146
Shawn McCarneyb4d18a42020-06-02 10:27:05 -0500147TEST(DeviceTests, Close)
148{
149 // Test where works: I2C interface is not open
150 {
151 // Create mock I2CInterface
152 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
153 std::make_unique<i2c::MockedI2CInterface>();
154 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false));
155 EXPECT_CALL(*i2cInterface, close).Times(0);
156
157 // Create Device
158 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
159 std::move(i2cInterface)};
160
161 // Close Device
162 journal::clear();
163 device.close();
164 EXPECT_EQ(journal::getErrMessages().size(), 0);
165 }
166
167 // Test where works: I2C interface is open
168 {
169 // Create mock I2CInterface
170 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
171 std::make_unique<i2c::MockedI2CInterface>();
172 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
173 EXPECT_CALL(*i2cInterface, close).Times(1);
174
175 // Create Device
176 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
177 std::move(i2cInterface)};
178
179 // Close Device
180 journal::clear();
181 device.close();
182 EXPECT_EQ(journal::getErrMessages().size(), 0);
183 }
184
185 // Test where fails: closing I2C interface fails
186 {
187 // Create mock I2CInterface
188 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
189 std::make_unique<i2c::MockedI2CInterface>();
190 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
191 EXPECT_CALL(*i2cInterface, close)
192 .Times(1)
193 .WillOnce(Throw(
194 i2c::I2CException{"Failed to close", "/dev/i2c-1", 0x70}));
195
196 // Create Device
197 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
198 std::move(i2cInterface)};
199
200 // Close Device
201 journal::clear();
202 device.close();
203 std::vector<std::string> expectedErrMessages{
204 "I2CException: Failed to close: bus /dev/i2c-1, addr 0x70",
205 "Unable to close device vdd_reg"};
206 EXPECT_EQ(journal::getErrMessages(), expectedErrMessages);
207 }
208}
209
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500210TEST(DeviceTests, Configure)
211{
212 // Test where Configuration and Rails were not specified in constructor
213 {
Bob King5cfe5102020-07-30 16:26:18 +0800214 // Create mock services. No logging should occur.
Bob King23243f82020-07-29 10:38:57 +0800215 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800216 MockJournal& journal = services.getMockJournal();
217 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
218 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800219
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500220 // Create Device
221 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
222 std::unique_ptr<Device> device = std::make_unique<Device>(
223 "reg1", true, "/system/chassis/motherboard/reg1",
224 std::move(i2cInterface));
225 Device* devicePtr = device.get();
226
227 // Create Chassis that contains Device
228 std::vector<std::unique_ptr<Device>> devices{};
229 devices.emplace_back(std::move(device));
230 std::unique_ptr<Chassis> chassis =
231 std::make_unique<Chassis>(1, std::move(devices));
232 Chassis* chassisPtr = chassis.get();
233
234 // Create System that contains Chassis
235 std::vector<std::unique_ptr<Rule>> rules{};
236 std::vector<std::unique_ptr<Chassis>> chassisVec{};
237 chassisVec.emplace_back(std::move(chassis));
238 System system{std::move(rules), std::move(chassisVec)};
239
Bob King5cfe5102020-07-30 16:26:18 +0800240 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800241 devicePtr->configure(services, system, *chassisPtr);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500242 }
243
244 // Test where Configuration and Rails were specified in constructor
245 {
246 std::vector<std::unique_ptr<Rail>> rails{};
247
Bob King5cfe5102020-07-30 16:26:18 +0800248 // Create mock services. Expect logDebug() to be called.
249 // For the Device and both Rails, should execute the Configuration
250 // and log a debug message.
251 MockServices services{};
252 MockJournal& journal = services.getMockJournal();
253 EXPECT_CALL(journal, logDebug("Configuring reg1")).Times(1);
254 EXPECT_CALL(journal, logDebug("Configuring vdd0: volts=1.300000"))
255 .Times(1);
256 EXPECT_CALL(journal, logDebug("Configuring vio0: volts=3.200000"))
257 .Times(1);
258 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
259
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500260 // Create Rail vdd0
261 {
262 // Create Configuration for Rail
263 std::optional<double> volts{1.3};
264 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
265 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
266 std::vector<std::unique_ptr<Action>> actions{};
267 actions.emplace_back(std::move(action));
268 std::unique_ptr<Configuration> configuration =
269 std::make_unique<Configuration>(volts, std::move(actions));
270
271 // Create Rail
272 std::unique_ptr<Rail> rail =
273 std::make_unique<Rail>("vdd0", std::move(configuration));
274 rails.emplace_back(std::move(rail));
275 }
276
277 // Create Rail vio0
278 {
279 // Create Configuration for Rail
280 std::optional<double> volts{3.2};
281 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
282 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
283 std::vector<std::unique_ptr<Action>> actions{};
284 actions.emplace_back(std::move(action));
285 std::unique_ptr<Configuration> configuration =
286 std::make_unique<Configuration>(volts, std::move(actions));
287
288 // Create Rail
289 std::unique_ptr<Rail> rail =
290 std::make_unique<Rail>("vio0", std::move(configuration));
291 rails.emplace_back(std::move(rail));
292 }
293
294 // Create Configuration for Device
295 std::optional<double> volts{};
296 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
297 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
298 std::vector<std::unique_ptr<Action>> actions{};
299 actions.emplace_back(std::move(action));
300 std::unique_ptr<Configuration> configuration =
301 std::make_unique<Configuration>(volts, std::move(actions));
302
303 // Create Device
304 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
305 std::unique_ptr<PresenceDetection> presenceDetection{};
306 std::unique_ptr<Device> device = std::make_unique<Device>(
307 "reg1", true, "/system/chassis/motherboard/reg1",
308 std::move(i2cInterface), std::move(presenceDetection),
309 std::move(configuration), std::move(rails));
310 Device* devicePtr = device.get();
311
312 // Create Chassis that contains Device
313 std::vector<std::unique_ptr<Device>> devices{};
314 devices.emplace_back(std::move(device));
315 std::unique_ptr<Chassis> chassis =
316 std::make_unique<Chassis>(1, std::move(devices));
317 Chassis* chassisPtr = chassis.get();
318
319 // Create System that contains Chassis
320 std::vector<std::unique_ptr<Rule>> rules{};
321 std::vector<std::unique_ptr<Chassis>> chassisVec{};
322 chassisVec.emplace_back(std::move(chassis));
323 System system{std::move(rules), std::move(chassisVec)};
324
Bob King5cfe5102020-07-30 16:26:18 +0800325 // Call configure().
Bob King23243f82020-07-29 10:38:57 +0800326 devicePtr->configure(services, system, *chassisPtr);
Shawn McCarneyeb7bec42020-04-14 09:38:15 -0500327 }
328}
329
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500330TEST(DeviceTests, GetConfiguration)
Shawn McCarneya2461b32019-10-24 18:53:01 -0500331{
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500332 // Test where Configuration was not specified in constructor
333 {
334 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
335 std::move(createI2CInterface())};
336 EXPECT_EQ(device.getConfiguration(), nullptr);
337 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600338
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500339 // Test where Configuration was specified in constructor
340 {
341 std::unique_ptr<PresenceDetection> presenceDetection{};
342
343 // Create Configuration
344 std::optional<double> volts{3.2};
345 std::vector<std::unique_ptr<Action>> actions{};
346 actions.push_back(std::make_unique<MockAction>());
347 actions.push_back(std::make_unique<MockAction>());
348 std::unique_ptr<Configuration> configuration =
349 std::make_unique<Configuration>(volts, std::move(actions));
350
351 // Create Device
352 Device device{"vdd_reg",
353 true,
354 "/system/chassis/motherboard/reg2",
355 std::move(createI2CInterface()),
356 std::move(presenceDetection),
357 std::move(configuration)};
358 EXPECT_NE(device.getConfiguration(), nullptr);
359 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true);
360 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2);
361 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2);
362 }
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600363}
364
365TEST(DeviceTests, GetFRU)
366{
367 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
368 std::move(createI2CInterface())};
369 EXPECT_EQ(device.getFRU(), "/system/chassis/motherboard/reg2");
370}
371
372TEST(DeviceTests, GetI2CInterface)
373{
374 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface();
375 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get();
376 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
377 std::move(i2cInterface)};
378 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr);
Shawn McCarneya2461b32019-10-24 18:53:01 -0500379}
Shawn McCarney0b1a0e72020-03-11 18:01:44 -0500380
381TEST(DeviceTests, GetID)
382{
383 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
384 std::move(createI2CInterface())};
385 EXPECT_EQ(device.getID(), "vdd_reg");
386}
387
388TEST(DeviceTests, GetPresenceDetection)
389{
390 // Test where PresenceDetection was not specified in constructor
391 {
392 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
393 std::move(createI2CInterface())};
394 EXPECT_EQ(device.getPresenceDetection(), nullptr);
395 }
396
397 // Test where PresenceDetection was specified in constructor
398 {
399 // Create PresenceDetection
400 std::vector<std::unique_ptr<Action>> actions{};
401 actions.push_back(std::make_unique<MockAction>());
402 std::unique_ptr<PresenceDetection> presenceDetection =
403 std::make_unique<PresenceDetection>(std::move(actions));
404
405 // Create Device
406 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
407 std::move(createI2CInterface()),
408 std::move(presenceDetection)};
409 EXPECT_NE(device.getPresenceDetection(), nullptr);
410 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1);
411 }
412}
413
414TEST(DeviceTests, GetRails)
415{
416 // Test where no rails were specified in constructor
417 {
418 Device device{"vdd_reg", true, "/system/chassis/motherboard/reg2",
419 std::move(createI2CInterface())};
420 EXPECT_EQ(device.getRails().size(), 0);
421 }
422
423 // Test where rails were specified in constructor
424 {
425 std::unique_ptr<PresenceDetection> presenceDetection{};
426 std::unique_ptr<Configuration> configuration{};
427
428 // Create vector of Rail objects
429 std::vector<std::unique_ptr<Rail>> rails{};
430 rails.push_back(std::make_unique<Rail>("vdd0"));
431 rails.push_back(std::make_unique<Rail>("vdd1"));
432
433 // Create Device
434 Device device{"vdd_reg",
435 false,
436 "/system/chassis/motherboard/reg2",
437 std::move(createI2CInterface()),
438 std::move(presenceDetection),
439 std::move(configuration),
440 std::move(rails)};
441 EXPECT_EQ(device.getRails().size(), 2);
442 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0");
443 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1");
444 }
445}
446
447TEST(DeviceTests, IsRegulator)
448{
449 Device device{"vdd_reg", false, "/system/chassis/motherboard/reg2",
450 std::move(createI2CInterface())};
451 EXPECT_EQ(device.isRegulator(), false);
452}
Bob King8e1cd0b2020-07-08 13:30:27 +0800453
454TEST(DeviceTests, MonitorSensors)
455{
456 // Test where Rails were not specified in constructor
457 {
Bob King8a552922020-08-05 17:02:31 +0800458 // Create mock services. No logging should occur.
459 MockServices services{};
460 MockJournal& journal = services.getMockJournal();
461 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
462 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
463
Bob King8e1cd0b2020-07-08 13:30:27 +0800464 // Create mock I2CInterface. A two-byte read should NOT occur.
465 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
466 std::make_unique<i2c::MockedI2CInterface>();
467 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint16_t&>())).Times(0);
468
469 // Create Device
470 std::unique_ptr<Device> device = std::make_unique<Device>(
471 "reg1", true, "/system/chassis/motherboard/reg1",
472 std::move(i2cInterface));
473 Device* devicePtr = device.get();
474
475 // Create Chassis that contains Device
476 std::vector<std::unique_ptr<Device>> devices{};
477 devices.emplace_back(std::move(device));
478 std::unique_ptr<Chassis> chassis =
479 std::make_unique<Chassis>(1, std::move(devices));
480 Chassis* chassisPtr = chassis.get();
481
482 // Create System that contains Chassis
483 std::vector<std::unique_ptr<Rule>> rules{};
484 std::vector<std::unique_ptr<Chassis>> chassisVec{};
485 chassisVec.emplace_back(std::move(chassis));
486 System system{std::move(rules), std::move(chassisVec)};
487
Bob King8a552922020-08-05 17:02:31 +0800488 // Call monitorSensors().
489 devicePtr->monitorSensors(services, system, *chassisPtr);
Bob King8e1cd0b2020-07-08 13:30:27 +0800490 }
491
492 // Test where Rails were specified in constructor
493 {
Bob King8a552922020-08-05 17:02:31 +0800494 // Create mock services. No logging should occur.
495 MockServices services{};
496 MockJournal& journal = services.getMockJournal();
497 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0);
498 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
499
Bob King8e1cd0b2020-07-08 13:30:27 +0800500 std::vector<std::unique_ptr<Rail>> rails{};
501
502 // Create PMBusReadSensorAction
503 pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
504 uint8_t command = 0x8C;
505 pmbus_utils::SensorDataFormat format{
506 pmbus_utils::SensorDataFormat::linear_11};
507 std::optional<int8_t> exponent{};
508 std::unique_ptr<PMBusReadSensorAction> action =
509 std::make_unique<PMBusReadSensorAction>(type, command, format,
510 exponent);
511
512 // Create mock I2CInterface. A two-byte read should occur.
513 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
514 std::make_unique<i2c::MockedI2CInterface>();
515 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
516 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
517 .Times(1);
518
519 // Create SensorMonitoring
520 std::vector<std::unique_ptr<Action>> actions{};
521 actions.emplace_back(std::move(action));
522 std::unique_ptr<SensorMonitoring> sensorMonitoring =
523 std::make_unique<SensorMonitoring>(std::move(actions));
524
525 // Create Rail
526 std::unique_ptr<Configuration> configuration{};
527 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
528 "vdd0", std::move(configuration), std::move(sensorMonitoring));
529 rails.emplace_back(std::move(rail));
530
531 // Create Device
532 std::unique_ptr<PresenceDetection> presenceDetection{};
533 std::unique_ptr<Configuration> deviceConfiguration{};
534 std::unique_ptr<Device> device = std::make_unique<Device>(
535 "reg1", true, "/system/chassis/motherboard/reg1",
536 std::move(i2cInterface), std::move(presenceDetection),
537 std::move(deviceConfiguration), std::move(rails));
538 Device* devicePtr = device.get();
539
540 // Create Chassis that contains Device
541 std::vector<std::unique_ptr<Device>> devices{};
542 devices.emplace_back(std::move(device));
543 std::unique_ptr<Chassis> chassis =
544 std::make_unique<Chassis>(1, std::move(devices));
545 Chassis* chassisPtr = chassis.get();
546
547 // Create System that contains Chassis
548 std::vector<std::unique_ptr<Rule>> rules{};
549 std::vector<std::unique_ptr<Chassis>> chassisVec{};
550 chassisVec.emplace_back(std::move(chassis));
551 System system{std::move(rules), std::move(chassisVec)};
552
553 // Call monitorSensors().
Bob King8a552922020-08-05 17:02:31 +0800554 devicePtr->monitorSensors(services, system, *chassisPtr);
Bob King8e1cd0b2020-07-08 13:30:27 +0800555 }
556}