1 /** 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" 21 #include "mock_services.hpp" 22 #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 38 using namespace phosphor::power::regulators; 39 40 using ::testing::A; 41 using ::testing::Return; 42 using ::testing::SetArgReferee; 43 using ::testing::Throw; 44 using ::testing::TypedEq; 45 46 TEST(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 106 TEST(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 127 // Create Device, IDMap, MockServices, and ActionEnvironment 128 Device device{ 129 "reg1", true, 130 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 131 std::move(i2cInterface)}; 132 IDMap idMap{}; 133 idMap.addDevice(device); 134 MockServices services{}; 135 ActionEnvironment env{idMap, "reg1", services}; 136 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 170 // Create Device, IDMap, MockServices, and ActionEnvironment. Set 171 // volts value to 3.3 in ActionEnvironment. 172 Device device{ 173 "reg1", true, 174 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 175 std::move(i2cInterface)}; 176 IDMap idMap{}; 177 idMap.addDevice(device); 178 MockServices services{}; 179 ActionEnvironment env{idMap, "reg1", services}; 180 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 { 199 // Create IDMap, MockServices, and ActionEnvironment 200 IDMap idMap{}; 201 MockServices services{}; 202 ActionEnvironment env{idMap, "reg1", services}; 203 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 { 228 // Create IDMap, MockServices, and ActionEnvironment 229 IDMap idMap{}; 230 MockServices services{}; 231 ActionEnvironment env{idMap, "reg1", services}; 232 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 266 // Create Device, IDMap, MockServices, and ActionEnvironment 267 Device device{ 268 "reg1", true, 269 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 270 std::move(i2cInterface)}; 271 IDMap idMap{}; 272 idMap.addDevice(device); 273 MockServices services{}; 274 ActionEnvironment env{idMap, "reg1", services}; 275 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 326 // Create Device, IDMap, MockServices, and ActionEnvironment 327 Device device{ 328 "reg1", true, 329 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 330 std::move(i2cInterface)}; 331 IDMap idMap{}; 332 idMap.addDevice(device); 333 MockServices services{}; 334 ActionEnvironment env{idMap, "reg1", services}; 335 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 EXPECT_EQ(pe.getDeviceID(), "reg1"); 362 EXPECT_EQ(pe.getInventoryPath(), "/xyz/openbmc_project/inventory/" 363 "system/chassis/motherboard/reg1"); 364 } 365 catch (...) 366 { 367 ADD_FAILURE() << "Should not have caught exception."; 368 } 369 } 370 catch (...) 371 { 372 ADD_FAILURE() << "Should not have caught exception."; 373 } 374 375 // Test where fails: Unable to write VOUT_COMMAND 376 try 377 { 378 // Create mock I2CInterface. Expect action to do the following: 379 // * will not read from VOUT_MODE 380 // * will try to write 0x014D to VOUT_COMMAND; exception will be thrown 381 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 382 std::make_unique<i2c::MockedI2CInterface>(); 383 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 384 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0); 385 EXPECT_CALL(*i2cInterface, 386 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D))) 387 .Times(1) 388 .WillOnce(Throw(i2c::I2CException{"Failed to write word data", 389 "/dev/i2c-1", 0x70})); 390 391 // Create Device, IDMap, MockServices, and ActionEnvironment 392 Device device{ 393 "reg1", true, 394 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 395 std::move(i2cInterface)}; 396 IDMap idMap{}; 397 idMap.addDevice(device); 398 MockServices services{}; 399 ActionEnvironment env{idMap, "reg1", services}; 400 401 // Create and execute action 402 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D 403 std::optional<double> volts{1.3}; 404 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 405 std::optional<int8_t> exponent{-8}; 406 bool isVerified{false}; 407 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 408 action.execute(env); 409 ADD_FAILURE() << "Should not have reached this line."; 410 } 411 catch (const ActionError& e) 412 { 413 EXPECT_STREQ(e.what(), 414 "ActionError: pmbus_write_vout_command: { volts: 1.3, " 415 "format: linear, exponent: -8, is_verified: false }"); 416 try 417 { 418 // Re-throw inner I2CException 419 std::rethrow_if_nested(e); 420 ADD_FAILURE() << "Should not have reached this line."; 421 } 422 catch (const i2c::I2CException& ie) 423 { 424 EXPECT_STREQ(ie.what(), "I2CException: Failed to write word data: " 425 "bus /dev/i2c-1, addr 0x70"); 426 } 427 catch (...) 428 { 429 ADD_FAILURE() << "Should not have caught exception."; 430 } 431 } 432 catch (...) 433 { 434 ADD_FAILURE() << "Should not have caught exception."; 435 } 436 437 // Test where fails: Unable to read VOUT_COMMAND 438 try 439 { 440 // Create mock I2CInterface. Expect action to do the following: 441 // * will not read from VOUT_MODE 442 // * will write 0x014D to VOUT_COMMAND 443 // * will try to read from VOUT_COMMAND; exception will be thrown 444 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 445 std::make_unique<i2c::MockedI2CInterface>(); 446 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 447 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0); 448 EXPECT_CALL(*i2cInterface, 449 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D))) 450 .Times(1); 451 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x21), A<uint16_t&>())) 452 .Times(1) 453 .WillOnce(Throw(i2c::I2CException{"Failed to read word data", 454 "/dev/i2c-1", 0x70})); 455 456 // Create Device, IDMap, MockServices, and ActionEnvironment 457 Device device{ 458 "reg1", true, 459 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 460 std::move(i2cInterface)}; 461 IDMap idMap{}; 462 idMap.addDevice(device); 463 MockServices services{}; 464 ActionEnvironment env{idMap, "reg1", services}; 465 466 // Create and execute action 467 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D 468 std::optional<double> volts{1.3}; 469 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 470 std::optional<int8_t> exponent{-8}; 471 bool isVerified{true}; 472 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 473 action.execute(env); 474 ADD_FAILURE() << "Should not have reached this line."; 475 } 476 catch (const ActionError& e) 477 { 478 EXPECT_STREQ(e.what(), 479 "ActionError: pmbus_write_vout_command: { volts: 1.3, " 480 "format: linear, exponent: -8, is_verified: true }"); 481 try 482 { 483 // Re-throw inner I2CException 484 std::rethrow_if_nested(e); 485 ADD_FAILURE() << "Should not have reached this line."; 486 } 487 catch (const i2c::I2CException& ie) 488 { 489 EXPECT_STREQ(ie.what(), "I2CException: Failed to read word data: " 490 "bus /dev/i2c-1, addr 0x70"); 491 } 492 catch (...) 493 { 494 ADD_FAILURE() << "Should not have caught exception."; 495 } 496 } 497 catch (...) 498 { 499 ADD_FAILURE() << "Should not have caught exception."; 500 } 501 502 // Test where fails: Write verification error 503 try 504 { 505 // Create mock I2CInterface. Expect action to do the following: 506 // * will not read from VOUT_MODE 507 // * will write 0x014D to VOUT_COMMAND 508 // * will read 0x014C from VOUT_COMMAND (not equal to 0x014D) 509 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 510 std::make_unique<i2c::MockedI2CInterface>(); 511 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 512 EXPECT_CALL(*i2cInterface, read(A<uint8_t>(), A<uint8_t&>())).Times(0); 513 EXPECT_CALL(*i2cInterface, 514 write(TypedEq<uint8_t>(0x21), TypedEq<uint16_t>(0x014D))) 515 .Times(1); 516 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x21), A<uint16_t&>())) 517 .Times(1) 518 .WillOnce(SetArgReferee<1>(0x014C)); 519 520 // Create Device, IDMap, MockServices, and ActionEnvironment 521 Device device{ 522 "reg1", true, 523 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 524 std::move(i2cInterface)}; 525 IDMap idMap{}; 526 idMap.addDevice(device); 527 MockServices services{}; 528 ActionEnvironment env{idMap, "reg1", services}; 529 530 // Create and execute action 531 // Linear format volts value = (1.3 / 2^(-8)) = 332.8 = 333 = 0x014D 532 std::optional<double> volts{1.3}; 533 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 534 std::optional<int8_t> exponent{-8}; 535 bool isVerified{true}; 536 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 537 action.execute(env); 538 ADD_FAILURE() << "Should not have reached this line."; 539 } 540 catch (const ActionError& e) 541 { 542 EXPECT_STREQ(e.what(), 543 "ActionError: pmbus_write_vout_command: { volts: 1.3, " 544 "format: linear, exponent: -8, is_verified: true }"); 545 try 546 { 547 // Re-throw inner WriteVerificationError 548 std::rethrow_if_nested(e); 549 ADD_FAILURE() << "Should not have reached this line."; 550 } 551 catch (const WriteVerificationError& we) 552 { 553 EXPECT_STREQ( 554 we.what(), 555 "WriteVerificationError: device: reg1, register: VOUT_COMMAND, " 556 "value_written: 0x14D, value_read: 0x14C"); 557 EXPECT_EQ(we.getDeviceID(), "reg1"); 558 EXPECT_EQ(we.getInventoryPath(), "/xyz/openbmc_project/inventory/" 559 "system/chassis/motherboard/reg1"); 560 } 561 catch (...) 562 { 563 ADD_FAILURE() << "Should not have caught exception."; 564 } 565 } 566 catch (...) 567 { 568 ADD_FAILURE() << "Should not have caught exception."; 569 } 570 } 571 572 TEST(PMBusWriteVoutCommandActionTests, GetExponent) 573 { 574 std::optional<double> volts{1.3}; 575 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 576 bool isVerified{true}; 577 578 // Exponent value was specified 579 { 580 std::optional<int8_t> exponent{-9}; 581 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 582 EXPECT_EQ(action.getExponent().has_value(), true); 583 EXPECT_EQ(action.getExponent().value(), -9); 584 } 585 586 // Exponent value was not specified 587 { 588 std::optional<int8_t> exponent{}; 589 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 590 EXPECT_EQ(action.getExponent().has_value(), false); 591 } 592 } 593 594 TEST(PMBusWriteVoutCommandActionTests, GetFormat) 595 { 596 std::optional<double> volts{}; 597 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 598 std::optional<int8_t> exponent{}; 599 bool isVerified{false}; 600 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 601 EXPECT_EQ(action.getFormat(), pmbus_utils::VoutDataFormat::linear); 602 } 603 604 TEST(PMBusWriteVoutCommandActionTests, GetVolts) 605 { 606 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 607 std::optional<int8_t> exponent{-8}; 608 bool isVerified{true}; 609 610 // Volts value was specified 611 { 612 std::optional<double> volts{1.3}; 613 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 614 EXPECT_EQ(action.getVolts().has_value(), true); 615 EXPECT_EQ(action.getVolts().value(), 1.3); 616 } 617 618 // Volts value was not specified 619 { 620 std::optional<double> volts{}; 621 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 622 EXPECT_EQ(action.getVolts().has_value(), false); 623 } 624 } 625 626 TEST(PMBusWriteVoutCommandActionTests, IsVerified) 627 { 628 std::optional<double> volts{1.3}; 629 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 630 std::optional<int8_t> exponent{-8}; 631 bool isVerified{true}; 632 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 633 EXPECT_EQ(action.isVerified(), true); 634 } 635 636 TEST(PMBusWriteVoutCommandActionTests, ToString) 637 { 638 // Test where volts value and exponent value are specified 639 { 640 std::optional<double> volts{1.3}; 641 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 642 std::optional<int8_t> exponent{-8}; 643 bool isVerified{true}; 644 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 645 EXPECT_EQ(action.toString(), 646 "pmbus_write_vout_command: { volts: 1.3, format: linear, " 647 "exponent: -8, is_verified: true }"); 648 } 649 650 // Test where volts value and exponent value are not specified 651 { 652 std::optional<double> volts{}; 653 pmbus_utils::VoutDataFormat format{pmbus_utils::VoutDataFormat::linear}; 654 std::optional<int8_t> exponent{}; 655 bool isVerified{false}; 656 PMBusWriteVoutCommandAction action{volts, format, exponent, isVerified}; 657 EXPECT_EQ( 658 action.toString(), 659 "pmbus_write_vout_command: { format: linear, is_verified: false }"); 660 } 661 } 662