blob: 47279be45d6c598cac8fc1d36383c728e688b36b [file] [log] [blame]
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -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 */
16#include "action.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050017#include "chassis.hpp"
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050018#include "configuration.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050019#include "device.hpp"
20#include "i2c_interface.hpp"
21#include "i2c_write_byte_action.hpp"
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050022#include "mock_action.hpp"
Shawn McCarney81a2f902021-03-23 21:41:34 -050023#include "mock_error_logging.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050024#include "mock_journal.hpp"
Bob King23243f82020-07-29 10:38:57 +080025#include "mock_services.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050026#include "mocked_i2c_interface.hpp"
27#include "pmbus_utils.hpp"
28#include "pmbus_write_vout_command_action.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050029#include "presence_detection.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050030#include "rail.hpp"
Shawn McCarney779b9562020-04-13 17:05:45 -050031#include "rule.hpp"
Shawn McCarney39765002020-04-09 18:03:26 -050032#include "system.hpp"
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050033
Shawn McCarney779b9562020-04-13 17:05:45 -050034#include <cstdint>
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050035#include <memory>
36#include <optional>
37#include <utility>
38#include <vector>
39
Shawn McCarney39765002020-04-09 18:03:26 -050040#include <gmock/gmock.h>
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050041#include <gtest/gtest.h>
42
43using namespace phosphor::power::regulators;
Shawn McCarney39765002020-04-09 18:03:26 -050044using namespace phosphor::power::regulators::pmbus_utils;
45
Bob King5cfe5102020-07-30 16:26:18 +080046using ::testing::A;
Shawn McCarney81a2f902021-03-23 21:41:34 -050047using ::testing::Ref;
Shawn McCarney39765002020-04-09 18:03:26 -050048using ::testing::Return;
49using ::testing::Throw;
50using ::testing::TypedEq;
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050051
52TEST(ConfigurationTests, Constructor)
53{
54 // Test where volts value specified
55 {
56 std::optional<double> volts{1.3};
57
58 std::vector<std::unique_ptr<Action>> actions{};
59 actions.push_back(std::make_unique<MockAction>());
60 actions.push_back(std::make_unique<MockAction>());
61
62 Configuration configuration(volts, std::move(actions));
63 EXPECT_EQ(configuration.getVolts().has_value(), true);
64 EXPECT_EQ(configuration.getVolts().value(), 1.3);
65 EXPECT_EQ(configuration.getActions().size(), 2);
66 }
67
68 // Test where volts value not specified
69 {
70 std::optional<double> volts{};
71
72 std::vector<std::unique_ptr<Action>> actions{};
73 actions.push_back(std::make_unique<MockAction>());
74
75 Configuration configuration(volts, std::move(actions));
76 EXPECT_EQ(configuration.getVolts().has_value(), false);
77 EXPECT_EQ(configuration.getActions().size(), 1);
78 }
79}
80
Bob King5cfe5102020-07-30 16:26:18 +080081// Test for execute(Services&, System&, Chassis&, Device&)
Shawn McCarney39765002020-04-09 18:03:26 -050082TEST(ConfigurationTests, ExecuteForDevice)
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -050083{
Shawn McCarney39765002020-04-09 18:03:26 -050084 // Test where works: Volts value not specified
85 {
Bob King5cfe5102020-07-30 16:26:18 +080086 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +080087 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +080088 MockJournal& journal = services.getMockJournal();
89 EXPECT_CALL(journal, logDebug("Configuring vdd_reg")).Times(1);
90 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +080091
Shawn McCarney39765002020-04-09 18:03:26 -050092 // Create I2CWriteByteAction with register 0x7C and value 0x0A
93 std::unique_ptr<I2CWriteByteAction> action =
94 std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
95
96 // Create mock I2CInterface. Expect action to write 0x0A to 0x7C.
97 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
98 std::make_unique<i2c::MockedI2CInterface>();
99 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
100 EXPECT_CALL(*i2cInterface,
101 write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
102 .Times(1);
103
104 // Create Configuration with no volts value specified
105 std::optional<double> volts{};
106 std::vector<std::unique_ptr<Action>> actions{};
107 actions.emplace_back(std::move(action));
108 std::unique_ptr<Configuration> configuration =
109 std::make_unique<Configuration>(volts, std::move(actions));
110 Configuration* configurationPtr = configuration.get();
111
112 // Create Device that contains Configuration
113 std::unique_ptr<PresenceDetection> presenceDetection{};
114 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800115 "vdd_reg", true,
116 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
Shawn McCarney39765002020-04-09 18:03:26 -0500117 std::move(i2cInterface), std::move(presenceDetection),
118 std::move(configuration));
119 Device* devicePtr = device.get();
120
121 // Create Chassis that contains Device
122 std::vector<std::unique_ptr<Device>> devices{};
123 devices.emplace_back(std::move(device));
124 std::unique_ptr<Chassis> chassis =
125 std::make_unique<Chassis>(1, std::move(devices));
126 Chassis* chassisPtr = chassis.get();
127
128 // Create System that contains Chassis
129 std::vector<std::unique_ptr<Rule>> rules{};
130 std::vector<std::unique_ptr<Chassis>> chassisVec{};
131 chassisVec.emplace_back(std::move(chassis));
132 System system{std::move(rules), std::move(chassisVec)};
133
134 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800135 configurationPtr->execute(services, system, *chassisPtr, *devicePtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500136 }
137
138 // Test where works: Volts value specified
139 {
Bob King5cfe5102020-07-30 16:26:18 +0800140 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800141 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800142 MockJournal& journal = services.getMockJournal();
143 EXPECT_CALL(journal, logDebug("Configuring vdd_reg: volts=1.300000"))
144 .Times(1);
145 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800146
Shawn McCarney39765002020-04-09 18:03:26 -0500147 // Create PMBusWriteVoutCommandAction. Do not specify a volts value
148 // because it will get a value of 1.3V from the
149 // ActionEnvironment/Configuration. Specify a -8 exponent.
150 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D.
151 std::optional<double> volts{};
152 std::unique_ptr<PMBusWriteVoutCommandAction> action =
153 std::make_unique<PMBusWriteVoutCommandAction>(
154 volts, pmbus_utils::VoutDataFormat::linear, -8, false);
155
156 // Create mock I2CInterface. Expect action to write 0x014D to
157 // VOUT_COMMAND (command/register 0x21).
158 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
159 std::make_unique<i2c::MockedI2CInterface>();
160 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
161 EXPECT_CALL(*i2cInterface,
162 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
163 .Times(1);
164
165 // Create Configuration with volts value 1.3V
166 std::vector<std::unique_ptr<Action>> actions{};
167 actions.emplace_back(std::move(action));
168 std::unique_ptr<Configuration> configuration =
169 std::make_unique<Configuration>(1.3, std::move(actions));
170 Configuration* configurationPtr = configuration.get();
171
172 // Create Device that contains Configuration
173 std::unique_ptr<PresenceDetection> presenceDetection{};
174 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800175 "vdd_reg", true,
176 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
Shawn McCarney39765002020-04-09 18:03:26 -0500177 std::move(i2cInterface), std::move(presenceDetection),
178 std::move(configuration));
179 Device* devicePtr = device.get();
180
181 // Create Chassis that contains Device
182 std::vector<std::unique_ptr<Device>> devices{};
183 devices.emplace_back(std::move(device));
184 std::unique_ptr<Chassis> chassis =
185 std::make_unique<Chassis>(1, std::move(devices));
186 Chassis* chassisPtr = chassis.get();
187
188 // Create System that contains Chassis
189 std::vector<std::unique_ptr<Rule>> rules{};
190 std::vector<std::unique_ptr<Chassis>> chassisVec{};
191 chassisVec.emplace_back(std::move(chassis));
192 System system{std::move(rules), std::move(chassisVec)};
193
194 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800195 configurationPtr->execute(services, system, *chassisPtr, *devicePtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500196 }
197
198 // Test where fails
199 {
Shawn McCarney81a2f902021-03-23 21:41:34 -0500200 // Create mock services. Expect logDebug(), logError(), and
201 // logI2CError() to be called.
Bob King23243f82020-07-29 10:38:57 +0800202 MockServices services{};
Shawn McCarney81a2f902021-03-23 21:41:34 -0500203 MockErrorLogging& errorLogging = services.getMockErrorLogging();
Bob King5cfe5102020-07-30 16:26:18 +0800204 MockJournal& journal = services.getMockJournal();
205 std::vector<std::string> expectedErrMessagesException{
206 "I2CException: Failed to write byte: bus /dev/i2c-1, addr 0x70",
207 "ActionError: i2c_write_byte: { register: 0x7C, value: 0xA, mask: "
208 "0xFF }"};
209 EXPECT_CALL(journal, logDebug("Configuring vdd_reg")).Times(1);
210 EXPECT_CALL(journal, logError(expectedErrMessagesException)).Times(1);
211 EXPECT_CALL(journal, logError("Unable to configure vdd_reg")).Times(1);
Shawn McCarney81a2f902021-03-23 21:41:34 -0500212 EXPECT_CALL(errorLogging,
213 logI2CError(Entry::Level::Warning, Ref(journal),
214 "/dev/i2c-1", 0x70, 0))
215 .Times(1);
Bob King23243f82020-07-29 10:38:57 +0800216
Shawn McCarney39765002020-04-09 18:03:26 -0500217 // Create I2CWriteByteAction with register 0x7C and value 0x0A
218 std::unique_ptr<I2CWriteByteAction> action =
219 std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
220
221 // Create mock I2CInterface. write() throws an I2CException.
222 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
223 std::make_unique<i2c::MockedI2CInterface>();
224 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
225 EXPECT_CALL(*i2cInterface,
226 write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
227 .Times(1)
228 .WillOnce(Throw(
229 i2c::I2CException{"Failed to write byte", "/dev/i2c-1", 0x70}));
230
231 // Create Configuration with no volts value specified
232 std::optional<double> volts{};
233 std::vector<std::unique_ptr<Action>> actions{};
234 actions.emplace_back(std::move(action));
235 std::unique_ptr<Configuration> configuration =
236 std::make_unique<Configuration>(volts, std::move(actions));
237 Configuration* configurationPtr = configuration.get();
238
239 // Create Device that contains Configuration
240 std::unique_ptr<PresenceDetection> presenceDetection{};
241 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800242 "vdd_reg", true,
243 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2",
Shawn McCarney39765002020-04-09 18:03:26 -0500244 std::move(i2cInterface), std::move(presenceDetection),
245 std::move(configuration));
246 Device* devicePtr = device.get();
247
248 // Create Chassis that contains Device
249 std::vector<std::unique_ptr<Device>> devices{};
250 devices.emplace_back(std::move(device));
251 std::unique_ptr<Chassis> chassis =
252 std::make_unique<Chassis>(1, std::move(devices));
253 Chassis* chassisPtr = chassis.get();
254
255 // Create System that contains Chassis
256 std::vector<std::unique_ptr<Rule>> rules{};
257 std::vector<std::unique_ptr<Chassis>> chassisVec{};
258 chassisVec.emplace_back(std::move(chassis));
259 System system{std::move(rules), std::move(chassisVec)};
260
261 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800262 configurationPtr->execute(services, system, *chassisPtr, *devicePtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500263 }
264}
265
Bob King5cfe5102020-07-30 16:26:18 +0800266// Test for execute(Services&, System&, Chassis&, Device&, Rail&)
Shawn McCarney39765002020-04-09 18:03:26 -0500267TEST(ConfigurationTests, ExecuteForRail)
268{
269 // Test where works: Volts value not specified
270 {
Bob King5cfe5102020-07-30 16:26:18 +0800271 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800272 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800273 MockJournal& journal = services.getMockJournal();
274 EXPECT_CALL(journal, logDebug("Configuring vio2")).Times(1);
275 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800276
Shawn McCarney39765002020-04-09 18:03:26 -0500277 // Create I2CWriteByteAction with register 0x7C and value 0x0A
278 std::unique_ptr<I2CWriteByteAction> action =
279 std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
280
281 // Create mock I2CInterface. Expect action to write 0x0A to 0x7C.
282 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
283 std::make_unique<i2c::MockedI2CInterface>();
284 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
285 EXPECT_CALL(*i2cInterface,
286 write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
287 .Times(1);
288
289 // Create Configuration with no volts value specified
290 std::optional<double> volts{};
291 std::vector<std::unique_ptr<Action>> actions{};
292 actions.emplace_back(std::move(action));
293 std::unique_ptr<Configuration> configuration =
294 std::make_unique<Configuration>(volts, std::move(actions));
295 Configuration* configurationPtr = configuration.get();
296
297 // Create Rail that contains Configuration
298 std::unique_ptr<Rail> rail =
299 std::make_unique<Rail>("vio2", std::move(configuration));
300 Rail* railPtr = rail.get();
301
302 // Create Device that contains Rail
303 std::unique_ptr<PresenceDetection> presenceDetection{};
304 std::unique_ptr<Configuration> deviceConfiguration{};
305 std::vector<std::unique_ptr<Rail>> rails{};
306 rails.emplace_back(std::move(rail));
307 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800308 "reg1", true,
309 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney39765002020-04-09 18:03:26 -0500310 std::move(i2cInterface), std::move(presenceDetection),
311 std::move(deviceConfiguration), std::move(rails));
312 Device* devicePtr = device.get();
313
314 // Create Chassis that contains Device
315 std::vector<std::unique_ptr<Device>> devices{};
316 devices.emplace_back(std::move(device));
317 std::unique_ptr<Chassis> chassis =
318 std::make_unique<Chassis>(1, std::move(devices));
319 Chassis* chassisPtr = chassis.get();
320
321 // Create System that contains Chassis
322 std::vector<std::unique_ptr<Rule>> rules{};
323 std::vector<std::unique_ptr<Chassis>> chassisVec{};
324 chassisVec.emplace_back(std::move(chassis));
325 System system{std::move(rules), std::move(chassisVec)};
326
327 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800328 configurationPtr->execute(services, system, *chassisPtr, *devicePtr,
329 *railPtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500330 }
331
332 // Test where works: Volts value specified
333 {
Bob King5cfe5102020-07-30 16:26:18 +0800334 // Create mock services. Expect logDebug() to be called.
Bob King23243f82020-07-29 10:38:57 +0800335 MockServices services{};
Bob King5cfe5102020-07-30 16:26:18 +0800336 MockJournal& journal = services.getMockJournal();
337 EXPECT_CALL(journal, logDebug("Configuring vio2: volts=1.300000"))
338 .Times(1);
339 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0);
Bob King23243f82020-07-29 10:38:57 +0800340
Shawn McCarney39765002020-04-09 18:03:26 -0500341 // Create PMBusWriteVoutCommandAction. Do not specify a volts value
342 // because it will get a value of 1.3V from the
343 // ActionEnvironment/Configuration. Specify a -8 exponent.
344 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D.
345 std::optional<double> volts{};
346 std::unique_ptr<PMBusWriteVoutCommandAction> action =
347 std::make_unique<PMBusWriteVoutCommandAction>(
348 volts, pmbus_utils::VoutDataFormat::linear, -8, false);
349
350 // Create mock I2CInterface. Expect action to write 0x014D to
351 // VOUT_COMMAND (command/register 0x21).
352 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
353 std::make_unique<i2c::MockedI2CInterface>();
354 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
355 EXPECT_CALL(*i2cInterface,
356 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
357 .Times(1);
358
359 // Create Configuration with volts value 1.3V
360 std::vector<std::unique_ptr<Action>> actions{};
361 actions.emplace_back(std::move(action));
362 std::unique_ptr<Configuration> configuration =
363 std::make_unique<Configuration>(1.3, std::move(actions));
364 Configuration* configurationPtr = configuration.get();
365
366 // Create Rail that contains Configuration
367 std::unique_ptr<Rail> rail =
368 std::make_unique<Rail>("vio2", std::move(configuration));
369 Rail* railPtr = rail.get();
370
371 // Create Device that contains Rail
372 std::unique_ptr<PresenceDetection> presenceDetection{};
373 std::unique_ptr<Configuration> deviceConfiguration{};
374 std::vector<std::unique_ptr<Rail>> rails{};
375 rails.emplace_back(std::move(rail));
376 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800377 "reg1", true,
378 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney39765002020-04-09 18:03:26 -0500379 std::move(i2cInterface), std::move(presenceDetection),
380 std::move(deviceConfiguration), std::move(rails));
381 Device* devicePtr = device.get();
382
383 // Create Chassis that contains Device
384 std::vector<std::unique_ptr<Device>> devices{};
385 devices.emplace_back(std::move(device));
386 std::unique_ptr<Chassis> chassis =
387 std::make_unique<Chassis>(1, std::move(devices));
388 Chassis* chassisPtr = chassis.get();
389
390 // Create System that contains Chassis
391 std::vector<std::unique_ptr<Rule>> rules{};
392 std::vector<std::unique_ptr<Chassis>> chassisVec{};
393 chassisVec.emplace_back(std::move(chassis));
394 System system{std::move(rules), std::move(chassisVec)};
395
396 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800397 configurationPtr->execute(services, system, *chassisPtr, *devicePtr,
398 *railPtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500399 }
400
401 // Test where fails
402 {
Shawn McCarney81a2f902021-03-23 21:41:34 -0500403 // Create mock services. Expect logDebug(), logError(), and logI2CError
404 // to be called.
Bob King23243f82020-07-29 10:38:57 +0800405 MockServices services{};
Shawn McCarney81a2f902021-03-23 21:41:34 -0500406 MockErrorLogging& errorLogging = services.getMockErrorLogging();
Bob King5cfe5102020-07-30 16:26:18 +0800407 MockJournal& journal = services.getMockJournal();
408 std::vector<std::string> expectedErrMessagesException{
409 "I2CException: Failed to write byte: bus /dev/i2c-1, addr 0x70",
410 "ActionError: i2c_write_byte: { register: 0x7C, value: 0xA, mask: "
411 "0xFF }"};
412 EXPECT_CALL(journal, logDebug("Configuring vio2")).Times(1);
413 EXPECT_CALL(journal, logError(expectedErrMessagesException)).Times(1);
414 EXPECT_CALL(journal, logError("Unable to configure vio2")).Times(1);
Shawn McCarney81a2f902021-03-23 21:41:34 -0500415 EXPECT_CALL(errorLogging,
416 logI2CError(Entry::Level::Warning, Ref(journal),
417 "/dev/i2c-1", 0x70, 0))
418 .Times(1);
Bob King23243f82020-07-29 10:38:57 +0800419
Shawn McCarney39765002020-04-09 18:03:26 -0500420 // Create I2CWriteByteAction with register 0x7C and value 0x0A
421 std::unique_ptr<I2CWriteByteAction> action =
422 std::make_unique<I2CWriteByteAction>(0x7C, 0x0A);
423
424 // Create mock I2CInterface. write() throws an I2CException.
425 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
426 std::make_unique<i2c::MockedI2CInterface>();
427 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
428 EXPECT_CALL(*i2cInterface,
429 write(TypedEq<uint8_t>(0x7C), TypedEq<uint8_t>(0x0A)))
430 .Times(1)
431 .WillOnce(Throw(
432 i2c::I2CException{"Failed to write byte", "/dev/i2c-1", 0x70}));
433
434 // Create Configuration with no volts value specified
435 std::optional<double> volts{};
436 std::vector<std::unique_ptr<Action>> actions{};
437 actions.emplace_back(std::move(action));
438 std::unique_ptr<Configuration> configuration =
439 std::make_unique<Configuration>(volts, std::move(actions));
440 Configuration* configurationPtr = configuration.get();
441
442 // Create Rail that contains Configuration
443 std::unique_ptr<Rail> rail =
444 std::make_unique<Rail>("vio2", std::move(configuration));
445 Rail* railPtr = rail.get();
446
447 // Create Device that contains Rail
448 std::unique_ptr<PresenceDetection> presenceDetection{};
449 std::unique_ptr<Configuration> deviceConfiguration{};
450 std::vector<std::unique_ptr<Rail>> rails{};
451 rails.emplace_back(std::move(rail));
452 std::unique_ptr<Device> device = std::make_unique<Device>(
Bob Kinga76898f2020-10-13 15:08:33 +0800453 "reg1", true,
454 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
Shawn McCarney39765002020-04-09 18:03:26 -0500455 std::move(i2cInterface), std::move(presenceDetection),
456 std::move(deviceConfiguration), std::move(rails));
457 Device* devicePtr = device.get();
458
459 // Create Chassis that contains Device
460 std::vector<std::unique_ptr<Device>> devices{};
461 devices.emplace_back(std::move(device));
462 std::unique_ptr<Chassis> chassis =
463 std::make_unique<Chassis>(1, std::move(devices));
464 Chassis* chassisPtr = chassis.get();
465
466 // Create System that contains Chassis
467 std::vector<std::unique_ptr<Rule>> rules{};
468 std::vector<std::unique_ptr<Chassis>> chassisVec{};
469 chassisVec.emplace_back(std::move(chassis));
470 System system{std::move(rules), std::move(chassisVec)};
471
472 // Execute Configuration
Bob King23243f82020-07-29 10:38:57 +0800473 configurationPtr->execute(services, system, *chassisPtr, *devicePtr,
474 *railPtr);
Shawn McCarney39765002020-04-09 18:03:26 -0500475 }
Shawn McCarneyd3a8aab2020-03-10 10:30:02 -0500476}
477
478TEST(ConfigurationTests, GetActions)
479{
480 std::optional<double> volts{1.3};
481
482 std::vector<std::unique_ptr<Action>> actions{};
483
484 MockAction* action1 = new MockAction{};
485 actions.push_back(std::unique_ptr<MockAction>{action1});
486
487 MockAction* action2 = new MockAction{};
488 actions.push_back(std::unique_ptr<MockAction>{action2});
489
490 Configuration configuration(volts, std::move(actions));
491 EXPECT_EQ(configuration.getActions().size(), 2);
492 EXPECT_EQ(configuration.getActions()[0].get(), action1);
493 EXPECT_EQ(configuration.getActions()[1].get(), action2);
494}
495
496TEST(ConfigurationTests, GetVolts)
497{
498 // Test where volts value specified
499 {
500 std::optional<double> volts{3.2};
501
502 std::vector<std::unique_ptr<Action>> actions{};
503 actions.push_back(std::make_unique<MockAction>());
504
505 Configuration configuration(volts, std::move(actions));
506 EXPECT_EQ(configuration.getVolts().has_value(), true);
507 EXPECT_EQ(configuration.getVolts().value(), 3.2);
508 }
509
510 // Test where volts value not specified
511 {
512 std::optional<double> volts{};
513
514 std::vector<std::unique_ptr<Action>> actions{};
515 actions.push_back(std::make_unique<MockAction>());
516
517 Configuration configuration(volts, std::move(actions));
518 EXPECT_EQ(configuration.getVolts().has_value(), false);
519 }
520}