blob: d515cadb23b1335bfaa5c478d35f95938f32dcc8 [file] [log] [blame]
Shawn McCarneya8119f22020-03-02 16:20:18 -06001/**
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_environment.hpp"
17#include "action_error.hpp"
18#include "device.hpp"
19#include "i2c_interface.hpp"
20#include "id_map.hpp"
Bob King73eacee2020-10-23 13:58:02 +080021#include "mock_services.hpp"
Shawn McCarneya8119f22020-03-02 16:20:18 -060022#include "mocked_i2c_interface.hpp"
23#include "pmbus_error.hpp"
24#include "pmbus_utils.hpp"
25#include "pmbus_write_vout_command_action.hpp"
26#include "write_verification_error.hpp"
27
28#include <cstdint>
29#include <memory>
30#include <optional>
31#include <stdexcept>
32#include <string>
33#include <utility>
34
35#include <gmock/gmock.h>
36#include <gtest/gtest.h>
37
38using namespace phosphor::power::regulators;
39
40using ::testing::A;
41using ::testing::Return;
42using ::testing::SetArgReferee;
43using ::testing::Throw;
44using ::testing::TypedEq;
45
46TEST(PMBusWriteVoutCommandActionTests, Constructor)
47{
48 // Test where works: Volts value and exponent value are specified
49 try
50 {
51 std::optional<double> volts{1.3};
52 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
53 std::optional<int8_t> exponent{-8};
54 bool isVerified{true};
55 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
56 EXPECT_EQ(action.getVolts().has_value(), true);
57 EXPECT_EQ(action.getVolts().value(), 1.3);
58 EXPECT_EQ(action.getFormat(), pmbus_utils::VoutDataFormat::linear);
59 EXPECT_EQ(action.getExponent().has_value(), true);
60 EXPECT_EQ(action.getExponent().value(), -8);
61 EXPECT_EQ(action.isVerified(), true);
62 }
63 catch (...)
64 {
65 ADD_FAILURE() << "Should not have caught exception.";
66 }
67
68 // Test where works: Volts value and exponent value are not specified
69 try
70 {
71 std::optional<double> volts{};
72 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
73 std::optional<int8_t> exponent{};
74 bool isVerified{false};
75 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
76 EXPECT_EQ(action.getVolts().has_value(), false);
77 EXPECT_EQ(action.getFormat(), pmbus_utils::VoutDataFormat::linear);
78 EXPECT_EQ(action.getExponent().has_value(), false);
79 EXPECT_EQ(action.isVerified(), false);
80 }
81 catch (...)
82 {
83 ADD_FAILURE() << "Should not have caught exception.";
84 }
85
86 // Test where fails: Data format is not linear
87 try
88 {
89 std::optional<double> volts{};
90 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::direct};
91 std::optional<int8_t> exponent{};
92 bool isVerified{false};
93 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
94 ADD_FAILURE() << "Should not have reached this line.";
95 }
96 catch (const std::invalid_argument& e)
97 {
98 EXPECT_STREQ(e.what(), "Unsupported data format specified");
99 }
100 catch (...)
101 {
102 ADD_FAILURE() << "Should not have caught exception.";
103 }
104}
105
106TEST(PMBusWriteVoutCommandActionTests, Execute)
107{
108 // Test where works: Volts value and exponent value defined in action;
109 // write is verified.
110 try
111 {
112 // Create mock I2CInterface. Expect action to do the following:
113 // * will not read from VOUT_MODE (command/register 0x20)
114 // * will write 0x014D to VOUT_COMMAND (command/register 0x21)
115 // * will read 0x014D from VOUT_COMMAND
116 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
117 std::make_unique<i2c::MockedI2CInterface>();
118 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
119 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
120 EXPECT_CALL(*i2cInterface,
121 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
122 .Times(1);
123 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x21), A<uint16_t&>()))
124 .Times(1)
125 .WillOnce(SetArgReferee<1>(0x014D));
126
Bob King73eacee2020-10-23 13:58:02 +0800127 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800128 Device device{
129 "reg1", true,
130 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
131 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600132 IDMap idMap{};
133 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800134 MockServices services{};
135 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600136
137 // Create and execute action
138 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D
139 std::optional<double> volts{1.3};
140 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
141 std::optional<int8_t> exponent{-8};
142 bool isVerified{true};
143 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
144 EXPECT_EQ(action.execute(env), true);
145 }
146 catch (...)
147 {
148 ADD_FAILURE() << "Should not have caught exception.";
149 }
150
151 // Test where works: Volts value defined in ActionEnvironment; exponent
152 // value defined in VOUT_MODE; write is not verified.
153 try
154 {
155 // Create mock I2CInterface. Expect action to do the following:
156 // * will read 0b0001'0111 (linear format, -9 exponent) from VOUT_MODE
157 // * will write 0x069A to VOUT_COMMAND
158 // * will not read from VOUT_COMMAND
159 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
160 std::make_unique<i2c::MockedI2CInterface>();
161 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
162 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x20), A<uint8_t&>()))
163 .Times(1)
164 .WillOnce(SetArgReferee<1>(0b0001'0111));
165 EXPECT_CALL(*i2cInterface,
166 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x069A)))
167 .Times(1);
168 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint16_t&>())).Times(0);
169
Bob King73eacee2020-10-23 13:58:02 +0800170 // Create Device, IDMap, MockServices, and ActionEnvironment. Set
171 // volts value to 3.3 in ActionEnvironment.
Bob Kinga76898f2020-10-13 15:08:33 +0800172 Device device{
173 "reg1", true,
174 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
175 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600176 IDMap idMap{};
177 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800178 MockServices services{};
179 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600180 env.setVolts(3.3);
181
182 // Create and execute action
183 // Linear format volts value = (3.3 / 2^(-9)) = 1689.6 = 1690 = 0x069A
184 std::optional<double> volts{};
185 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
186 std::optional<int8_t> exponent{};
187 bool isVerified{false};
188 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
189 EXPECT_EQ(action.execute(env), true);
190 }
191 catch (...)
192 {
193 ADD_FAILURE() << "Should not have caught exception.";
194 }
195
196 // Test where fails: No volts value defined
197 try
198 {
Bob King73eacee2020-10-23 13:58:02 +0800199 // Create IDMap, MockServices, and ActionEnvironment
Shawn McCarneya8119f22020-03-02 16:20:18 -0600200 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800201 MockServices services{};
202 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600203
204 // Create and execute action
205 std::optional<double> volts{};
206 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
207 std::optional<int8_t> exponent{-8};
208 bool isVerified{false};
209 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
210 action.execute(env);
211 ADD_FAILURE() << "Should not have reached this line.";
212 }
213 catch (const ActionError& e)
214 {
215 EXPECT_STREQ(
216 e.what(),
217 "ActionError: pmbus_write_vout_command: { format: linear, "
218 "exponent: -8, is_verified: false }: No volts value defined");
219 }
220 catch (...)
221 {
222 ADD_FAILURE() << "Should not have caught exception.";
223 }
224
225 // Test where fails: Unable to get I2C interface to current device
226 try
227 {
Bob King73eacee2020-10-23 13:58:02 +0800228 // Create IDMap, MockServices, and ActionEnvironment
Shawn McCarneya8119f22020-03-02 16:20:18 -0600229 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800230 MockServices services{};
231 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600232
233 // Create and execute action
234 std::optional<double> volts{1.3};
235 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
236 std::optional<int8_t> exponent{-8};
237 bool isVerified{false};
238 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
239 action.execute(env);
240 ADD_FAILURE() << "Should not have reached this line.";
241 }
242 catch (const std::invalid_argument& e)
243 {
244 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
245 }
246 catch (...)
247 {
248 ADD_FAILURE() << "Should not have caught exception.";
249 }
250
251 // Test where fails: Unable to read VOUT_MODE to get exponent
252 try
253 {
254 // Create mock I2CInterface. Expect action to do the following:
255 // * will try to read VOUT_MODE; exception will be thrown
256 // * will not write to VOUT_COMMAND due to exception
257 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
258 std::make_unique<i2c::MockedI2CInterface>();
259 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
260 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x20), A<uint8_t&>()))
261 .Times(1)
262 .WillOnce(Throw(
263 i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
264 EXPECT_CALL(*i2cInterface, write(A<uint8_t>(), A<uint16_t>())).Times(0);
265
Bob King73eacee2020-10-23 13:58:02 +0800266 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800267 Device device{
268 "reg1", true,
269 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
270 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600271 IDMap idMap{};
272 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800273 MockServices services{};
274 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600275
276 // Create and execute action
277 std::optional<double> volts{3.3};
278 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
279 std::optional<int8_t> exponent{};
280 bool isVerified{false};
281 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
282 action.execute(env);
283 ADD_FAILURE() << "Should not have reached this line.";
284 }
285 catch (const ActionError& e)
286 {
287 EXPECT_STREQ(e.what(),
288 "ActionError: pmbus_write_vout_command: { volts: 3.3, "
289 "format: linear, is_verified: false }");
290 try
291 {
292 // Re-throw inner I2CException
293 std::rethrow_if_nested(e);
294 ADD_FAILURE() << "Should not have reached this line.";
295 }
296 catch (const i2c::I2CException& ie)
297 {
298 EXPECT_STREQ(
299 ie.what(),
300 "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70");
301 }
302 catch (...)
303 {
304 ADD_FAILURE() << "Should not have caught exception.";
305 }
306 }
307 catch (...)
308 {
309 ADD_FAILURE() << "Should not have caught exception.";
310 }
311
312 // Test where fails: VOUT_MODE data format is not linear
313 try
314 {
315 // Create mock I2CInterface. Expect action to do the following:
316 // * will read 0b0010'0000 (vid data format) from VOUT_MODE
317 // * will not write to VOUT_COMMAND due to data format error
318 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
319 std::make_unique<i2c::MockedI2CInterface>();
320 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
321 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x20), A<uint8_t&>()))
322 .Times(1)
323 .WillOnce(SetArgReferee<1>(0b0010'0000));
324 EXPECT_CALL(*i2cInterface, write(A<uint8_t>(), A<uint16_t>())).Times(0);
325
Bob King73eacee2020-10-23 13:58:02 +0800326 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800327 Device device{
328 "reg1", true,
329 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
330 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600331 IDMap idMap{};
332 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800333 MockServices services{};
334 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600335
336 // Create and execute action
337 std::optional<double> volts{3.3};
338 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
339 std::optional<int8_t> exponent{};
340 bool isVerified{false};
341 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
342 action.execute(env);
343 ADD_FAILURE() << "Should not have reached this line.";
344 }
345 catch (const ActionError& e)
346 {
347 EXPECT_STREQ(e.what(),
348 "ActionError: pmbus_write_vout_command: { volts: 3.3, "
349 "format: linear, is_verified: false }");
350 try
351 {
352 // Re-throw inner PMBusError
353 std::rethrow_if_nested(e);
354 ADD_FAILURE() << "Should not have reached this line.";
355 }
356 catch (const PMBusError& pe)
357 {
358 EXPECT_STREQ(
359 pe.what(),
360 "PMBusError: VOUT_MODE contains unsupported data format");
361 }
362 catch (...)
363 {
364 ADD_FAILURE() << "Should not have caught exception.";
365 }
366 }
367 catch (...)
368 {
369 ADD_FAILURE() << "Should not have caught exception.";
370 }
371
372 // Test where fails: Unable to write VOUT_COMMAND
373 try
374 {
375 // Create mock I2CInterface. Expect action to do the following:
376 // * will not read from VOUT_MODE
377 // * will try to write 0x014D to VOUT_COMMAND; exception will be thrown
378 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
379 std::make_unique<i2c::MockedI2CInterface>();
380 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
381 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
382 EXPECT_CALL(*i2cInterface,
383 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
384 .Times(1)
385 .WillOnce(Throw(i2c::I2CException{"Failed to write word data",
386 "/dev/i2c-1", 0x70}));
387
Bob King73eacee2020-10-23 13:58:02 +0800388 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800389 Device device{
390 "reg1", true,
391 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
392 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600393 IDMap idMap{};
394 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800395 MockServices services{};
396 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600397
398 // Create and execute action
399 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D
400 std::optional<double> volts{1.3};
401 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
402 std::optional<int8_t> exponent{-8};
403 bool isVerified{false};
404 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
405 action.execute(env);
406 ADD_FAILURE() << "Should not have reached this line.";
407 }
408 catch (const ActionError& e)
409 {
410 EXPECT_STREQ(e.what(),
411 "ActionError: pmbus_write_vout_command: { volts: 1.3, "
412 "format: linear, exponent: -8, is_verified: false }");
413 try
414 {
415 // Re-throw inner I2CException
416 std::rethrow_if_nested(e);
417 ADD_FAILURE() << "Should not have reached this line.";
418 }
419 catch (const i2c::I2CException& ie)
420 {
421 EXPECT_STREQ(ie.what(), "I2CException: Failed to write word data: "
422 "bus /dev/i2c-1, addr 0x70");
423 }
424 catch (...)
425 {
426 ADD_FAILURE() << "Should not have caught exception.";
427 }
428 }
429 catch (...)
430 {
431 ADD_FAILURE() << "Should not have caught exception.";
432 }
433
434 // Test where fails: Unable to read VOUT_COMMAND
435 try
436 {
437 // Create mock I2CInterface. Expect action to do the following:
438 // * will not read from VOUT_MODE
439 // * will write 0x014D to VOUT_COMMAND
440 // * will try to read from VOUT_COMMAND; exception will be thrown
441 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
442 std::make_unique<i2c::MockedI2CInterface>();
443 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
444 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
445 EXPECT_CALL(*i2cInterface,
446 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
447 .Times(1);
448 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x21), A<uint16_t&>()))
449 .Times(1)
450 .WillOnce(Throw(i2c::I2CException{"Failed to read word data",
451 "/dev/i2c-1", 0x70}));
452
Bob King73eacee2020-10-23 13:58:02 +0800453 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800454 Device device{
455 "reg1", true,
456 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
457 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600458 IDMap idMap{};
459 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800460 MockServices services{};
461 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600462
463 // Create and execute action
464 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D
465 std::optional<double> volts{1.3};
466 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
467 std::optional<int8_t> exponent{-8};
468 bool isVerified{true};
469 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
470 action.execute(env);
471 ADD_FAILURE() << "Should not have reached this line.";
472 }
473 catch (const ActionError& e)
474 {
475 EXPECT_STREQ(e.what(),
476 "ActionError: pmbus_write_vout_command: { volts: 1.3, "
477 "format: linear, exponent: -8, is_verified: true }");
478 try
479 {
480 // Re-throw inner I2CException
481 std::rethrow_if_nested(e);
482 ADD_FAILURE() << "Should not have reached this line.";
483 }
484 catch (const i2c::I2CException& ie)
485 {
486 EXPECT_STREQ(ie.what(), "I2CException: Failed to read word data: "
487 "bus /dev/i2c-1, addr 0x70");
488 }
489 catch (...)
490 {
491 ADD_FAILURE() << "Should not have caught exception.";
492 }
493 }
494 catch (...)
495 {
496 ADD_FAILURE() << "Should not have caught exception.";
497 }
498
499 // Test where fails: Write verification error
500 try
501 {
502 // Create mock I2CInterface. Expect action to do the following:
503 // * will not read from VOUT_MODE
504 // * will write 0x014D to VOUT_COMMAND
505 // * will read 0x014C from VOUT_COMMAND (not equal to 0x014D)
506 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
507 std::make_unique<i2c::MockedI2CInterface>();
508 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
509 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0);
510 EXPECT_CALL(*i2cInterface,
511 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D)))
512 .Times(1);
513 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x21), A<uint16_t&>()))
514 .Times(1)
515 .WillOnce(SetArgReferee<1>(0x014C));
516
Bob King73eacee2020-10-23 13:58:02 +0800517 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800518 Device device{
519 "reg1", true,
520 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
521 std::move(i2cInterface)};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600522 IDMap idMap{};
523 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800524 MockServices services{};
525 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarneya8119f22020-03-02 16:20:18 -0600526
527 // Create and execute action
528 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D
529 std::optional<double> volts{1.3};
530 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
531 std::optional<int8_t> exponent{-8};
532 bool isVerified{true};
533 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
534 action.execute(env);
535 ADD_FAILURE() << "Should not have reached this line.";
536 }
537 catch (const ActionError& e)
538 {
539 EXPECT_STREQ(e.what(),
540 "ActionError: pmbus_write_vout_command: { volts: 1.3, "
541 "format: linear, exponent: -8, is_verified: true }");
542 try
543 {
544 // Re-throw inner WriteVerificationError
545 std::rethrow_if_nested(e);
546 ADD_FAILURE() << "Should not have reached this line.";
547 }
548 catch (const WriteVerificationError& we)
549 {
550 EXPECT_STREQ(
551 we.what(),
552 "WriteVerificationError: device: reg1, register: VOUT_COMMAND, "
553 "value_written: 0x14D, value_read: 0x14C");
554 }
555 catch (...)
556 {
557 ADD_FAILURE() << "Should not have caught exception.";
558 }
559 }
560 catch (...)
561 {
562 ADD_FAILURE() << "Should not have caught exception.";
563 }
564}
565
566TEST(PMBusWriteVoutCommandActionTests, GetExponent)
567{
568 std::optional<double> volts{1.3};
569 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
570 bool isVerified{true};
571
572 // Exponent value was specified
573 {
574 std::optional<int8_t> exponent{-9};
575 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
576 EXPECT_EQ(action.getExponent().has_value(), true);
577 EXPECT_EQ(action.getExponent().value(), -9);
578 }
579
580 // Exponent value was not specified
581 {
582 std::optional<int8_t> exponent{};
583 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
584 EXPECT_EQ(action.getExponent().has_value(), false);
585 }
586}
587
588TEST(PMBusWriteVoutCommandActionTests, GetFormat)
589{
590 std::optional<double> volts{};
591 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
592 std::optional<int8_t> exponent{};
593 bool isVerified{false};
594 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
595 EXPECT_EQ(action.getFormat(), pmbus_utils::VoutDataFormat::linear);
596}
597
598TEST(PMBusWriteVoutCommandActionTests, GetVolts)
599{
600 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
601 std::optional<int8_t> exponent{-8};
602 bool isVerified{true};
603
604 // Volts value was specified
605 {
606 std::optional<double> volts{1.3};
607 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
608 EXPECT_EQ(action.getVolts().has_value(), true);
609 EXPECT_EQ(action.getVolts().value(), 1.3);
610 }
611
612 // Volts value was not specified
613 {
614 std::optional<double> volts{};
615 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
616 EXPECT_EQ(action.getVolts().has_value(), false);
617 }
618}
619
620TEST(PMBusWriteVoutCommandActionTests, IsVerified)
621{
622 std::optional<double> volts{1.3};
623 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
624 std::optional<int8_t> exponent{-8};
625 bool isVerified{true};
626 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
627 EXPECT_EQ(action.isVerified(), true);
628}
629
630TEST(PMBusWriteVoutCommandActionTests, ToString)
631{
632 // Test where volts value and exponent value are specified
633 {
634 std::optional<double> volts{1.3};
635 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
636 std::optional<int8_t> exponent{-8};
637 bool isVerified{true};
638 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
639 EXPECT_EQ(action.toString(),
640 "pmbus_write_vout_command: { volts: 1.3, format: linear, "
641 "exponent: -8, is_verified: true }");
642 }
643
644 // Test where volts value and exponent value are not specified
645 {
646 std::optional<double> volts{};
647 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear};
648 std::optional<int8_t> exponent{};
649 bool isVerified{false};
650 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified};
651 EXPECT_EQ(
652 action.toString(),
653 "pmbus_write_vout_command: { format: linear, is_verified: false }");
654 }
655}