1 /** 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 */ 16 #include "action.hpp" 17 #include "chassis.hpp" 18 #include "configuration.hpp" 19 #include "device.hpp" 20 #include "i2c_interface.hpp" 21 #include "id_map.hpp" 22 #include "mock_action.hpp" 23 #include "mock_error_logging.hpp" 24 #include "mock_journal.hpp" 25 #include "mock_sensors.hpp" 26 #include "mock_services.hpp" 27 #include "mocked_i2c_interface.hpp" 28 #include "phase_fault_detection.hpp" 29 #include "presence_detection.hpp" 30 #include "rail.hpp" 31 #include "rule.hpp" 32 #include "sensor_monitoring.hpp" 33 #include "sensors.hpp" 34 #include "system.hpp" 35 #include "test_sdbus_error.hpp" 36 #include "test_utils.hpp" 37 38 #include <memory> 39 #include <optional> 40 #include <string> 41 #include <utility> 42 #include <vector> 43 44 #include <gmock/gmock.h> 45 #include <gtest/gtest.h> 46 47 using namespace phosphor::power::regulators; 48 using namespace phosphor::power::regulators::test_utils; 49 50 using ::testing::A; 51 using ::testing::Ref; 52 using ::testing::Return; 53 using ::testing::Throw; 54 using ::testing::TypedEq; 55 56 class DeviceTests : public ::testing::Test 57 { 58 public: 59 /** 60 * Constructor. 61 * 62 * Creates the Chassis and System objects needed for calling some Device 63 * methods. 64 */ 65 DeviceTests() : ::testing::Test{} 66 { 67 // Create Chassis 68 auto chassis = std::make_unique<Chassis>(1, chassisInvPath); 69 this->chassis = chassis.get(); 70 71 // Create System 72 std::vector<std::unique_ptr<Rule>> rules{}; 73 std::vector<std::unique_ptr<Chassis>> chassisVec{}; 74 chassisVec.emplace_back(std::move(chassis)); 75 this->system = 76 std::make_unique<System>(std::move(rules), std::move(chassisVec)); 77 } 78 79 protected: 80 const std::string deviceInvPath{ 81 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg2"}; 82 const std::string chassisInvPath{ 83 "/xyz/openbmc_project/inventory/system/chassis"}; 84 85 // Note: This pointer does NOT need to be explicitly deleted. The Chassis 86 // object is owned by the System object and will be automatically deleted. 87 Chassis* chassis{nullptr}; 88 89 std::unique_ptr<System> system{}; 90 }; 91 92 TEST_F(DeviceTests, Constructor) 93 { 94 // Test where only required parameters are specified 95 { 96 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 97 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get(); 98 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)}; 99 EXPECT_EQ(device.getID(), "vdd_reg"); 100 EXPECT_EQ(device.isRegulator(), true); 101 EXPECT_EQ(device.getFRU(), deviceInvPath); 102 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr); 103 EXPECT_EQ(device.getPresenceDetection(), nullptr); 104 EXPECT_EQ(device.getConfiguration(), nullptr); 105 EXPECT_EQ(device.getPhaseFaultDetection(), nullptr); 106 EXPECT_EQ(device.getRails().size(), 0); 107 } 108 109 // Test where all parameters are specified 110 { 111 // Create I2CInterface 112 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 113 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get(); 114 115 // Create PresenceDetection 116 std::vector<std::unique_ptr<Action>> actions{}; 117 actions.push_back(std::make_unique<MockAction>()); 118 auto presenceDetection = 119 std::make_unique<PresenceDetection>(std::move(actions)); 120 121 // Create Configuration 122 std::optional<double> volts{}; 123 actions.clear(); 124 actions.push_back(std::make_unique<MockAction>()); 125 actions.push_back(std::make_unique<MockAction>()); 126 auto configuration = 127 std::make_unique<Configuration>(volts, std::move(actions)); 128 129 // Create PhaseFaultDetection 130 actions.clear(); 131 actions.push_back(std::make_unique<MockAction>()); 132 actions.push_back(std::make_unique<MockAction>()); 133 actions.push_back(std::make_unique<MockAction>()); 134 auto phaseFaultDetection = 135 std::make_unique<PhaseFaultDetection>(std::move(actions)); 136 137 // Create vector of Rail objects 138 std::vector<std::unique_ptr<Rail>> rails{}; 139 rails.push_back(std::make_unique<Rail>("vdd0")); 140 rails.push_back(std::make_unique<Rail>("vdd1")); 141 142 // Create Device 143 Device device{"vdd_reg", 144 false, 145 deviceInvPath, 146 std::move(i2cInterface), 147 std::move(presenceDetection), 148 std::move(configuration), 149 std::move(phaseFaultDetection), 150 std::move(rails)}; 151 EXPECT_EQ(device.getID(), "vdd_reg"); 152 EXPECT_EQ(device.isRegulator(), false); 153 EXPECT_EQ(device.getFRU(), deviceInvPath); 154 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr); 155 EXPECT_NE(device.getPresenceDetection(), nullptr); 156 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1); 157 EXPECT_NE(device.getConfiguration(), nullptr); 158 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), false); 159 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2); 160 EXPECT_NE(device.getPhaseFaultDetection(), nullptr); 161 EXPECT_EQ(device.getPhaseFaultDetection()->getActions().size(), 3); 162 EXPECT_EQ(device.getRails().size(), 2); 163 } 164 } 165 166 TEST_F(DeviceTests, AddToIDMap) 167 { 168 std::unique_ptr<PresenceDetection> presenceDetection{}; 169 std::unique_ptr<Configuration> configuration{}; 170 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 171 172 // Create vector of Rail objects 173 std::vector<std::unique_ptr<Rail>> rails{}; 174 rails.push_back(std::make_unique<Rail>("vdd0")); 175 rails.push_back(std::make_unique<Rail>("vdd1")); 176 177 // Create Device 178 Device device{"vdd_reg", 179 false, 180 deviceInvPath, 181 std::move(createI2CInterface()), 182 std::move(presenceDetection), 183 std::move(configuration), 184 std::move(phaseFaultDetection), 185 std::move(rails)}; 186 187 // Add Device and Rail objects to an IDMap 188 IDMap idMap{}; 189 device.addToIDMap(idMap); 190 191 // Verify Device is in the IDMap 192 EXPECT_NO_THROW(idMap.getDevice("vdd_reg")); 193 EXPECT_THROW(idMap.getDevice("vio_reg"), std::invalid_argument); 194 195 // Verify all Rails are in the IDMap 196 EXPECT_NO_THROW(idMap.getRail("vdd0")); 197 EXPECT_NO_THROW(idMap.getRail("vdd1")); 198 EXPECT_THROW(idMap.getRail("vdd2"), std::invalid_argument); 199 } 200 201 TEST_F(DeviceTests, ClearCache) 202 { 203 // Test where Device does not contain a PresenceDetection object 204 try 205 { 206 Device device{"vdd_reg", false, deviceInvPath, 207 std::move(createI2CInterface())}; 208 device.clearCache(); 209 } 210 catch (...) 211 { 212 ADD_FAILURE() << "Should not have caught exception."; 213 } 214 215 // Test where Device contains a PresenceDetection object 216 { 217 // Create PresenceDetection 218 std::vector<std::unique_ptr<Action>> actions{}; 219 auto presenceDetection = 220 std::make_unique<PresenceDetection>(std::move(actions)); 221 PresenceDetection* presenceDetectionPtr = presenceDetection.get(); 222 223 // Create Device 224 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 225 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface), 226 std::move(presenceDetection)}; 227 228 // Cache presence value in PresenceDetection 229 MockServices services{}; 230 presenceDetectionPtr->execute(services, *system, *chassis, device); 231 EXPECT_TRUE(presenceDetectionPtr->getCachedPresence().has_value()); 232 233 // Clear cached data in Device 234 device.clearCache(); 235 236 // Verify presence value no longer cached in PresenceDetection 237 EXPECT_FALSE(presenceDetectionPtr->getCachedPresence().has_value()); 238 } 239 } 240 241 TEST_F(DeviceTests, ClearErrorHistory) 242 { 243 // Create SensorMonitoring. Will fail with a DBus exception. 244 auto action = std::make_unique<MockAction>(); 245 EXPECT_CALL(*action, execute) 246 .WillRepeatedly(Throw(TestSDBusError{"Unable to set sensor value"})); 247 std::vector<std::unique_ptr<Action>> actions{}; 248 actions.emplace_back(std::move(action)); 249 auto sensorMonitoring = 250 std::make_unique<SensorMonitoring>(std::move(actions)); 251 252 // Create Rail 253 std::unique_ptr<Configuration> configuration{}; 254 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration), 255 std::move(sensorMonitoring)); 256 257 // Create Device that contains Rail 258 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 259 std::unique_ptr<PresenceDetection> presenceDetection{}; 260 std::unique_ptr<Configuration> deviceConfiguration{}; 261 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 262 std::vector<std::unique_ptr<Rail>> rails{}; 263 rails.emplace_back(std::move(rail)); 264 Device device{"reg2", 265 true, 266 deviceInvPath, 267 std::move(i2cInterface), 268 std::move(presenceDetection), 269 std::move(deviceConfiguration), 270 std::move(phaseFaultDetection), 271 std::move(rails)}; 272 273 // Create mock services 274 MockServices services{}; 275 276 // Expect Sensors service to be called 5+5=10 times 277 MockSensors& sensors = services.getMockSensors(); 278 EXPECT_CALL(sensors, startRail).Times(10); 279 EXPECT_CALL(sensors, setValue).Times(0); 280 EXPECT_CALL(sensors, endRail).Times(10); 281 282 // Expect Journal service to be called 3+3=6 times to log error messages 283 MockJournal& journal = services.getMockJournal(); 284 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>())) 285 .Times(6); 286 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(6); 287 288 // Expect ErrorLogging service to be called 1+1=2 times to log a DBus error 289 MockErrorLogging& errorLogging = services.getMockErrorLogging(); 290 EXPECT_CALL(errorLogging, logDBusError).Times(2); 291 292 // Monitor sensors 5 times. Should fail every time, write to journal 3 293 // times, and log one error. 294 for (int i = 1; i <= 5; ++i) 295 { 296 device.monitorSensors(services, *system, *chassis); 297 } 298 299 // Clear error history 300 device.clearErrorHistory(); 301 302 // Monitor sensors 5 times again. Should fail every time, write to journal 303 // 3 times, and log one error. 304 for (int i = 1; i <= 5; ++i) 305 { 306 device.monitorSensors(services, *system, *chassis); 307 } 308 } 309 310 TEST_F(DeviceTests, Close) 311 { 312 // Test where works: I2C interface is not open 313 { 314 // Create mock I2CInterface 315 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 316 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false)); 317 EXPECT_CALL(*i2cInterface, close).Times(0); 318 319 // Create mock services. No logError should occur. 320 MockServices services{}; 321 MockJournal& journal = services.getMockJournal(); 322 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 323 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>())) 324 .Times(0); 325 326 // Create Device 327 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)}; 328 329 // Close Device 330 device.close(services); 331 } 332 333 // Test where works: I2C interface is open 334 { 335 // Create mock I2CInterface 336 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 337 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 338 EXPECT_CALL(*i2cInterface, close).Times(1); 339 340 // Create mock services. No logError should occur. 341 MockServices services{}; 342 MockJournal& journal = services.getMockJournal(); 343 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 344 EXPECT_CALL(journal, logError(A<const std::vector<std::string>&>())) 345 .Times(0); 346 347 // Create Device 348 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)}; 349 350 // Close Device 351 device.close(services); 352 } 353 354 // Test where fails: closing I2C interface fails 355 { 356 // Create mock I2CInterface 357 auto i2cInterface = std::make_unique<i2c::MockedI2CInterface>(); 358 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true)); 359 EXPECT_CALL(*i2cInterface, close) 360 .Times(1) 361 .WillOnce(Throw( 362 i2c::I2CException{"Failed to close", "/dev/i2c-1", 0x70})); 363 364 // Create mock services. Expect logError() and logI2CError() to be 365 // called. 366 MockServices services{}; 367 MockErrorLogging& errorLogging = services.getMockErrorLogging(); 368 MockJournal& journal = services.getMockJournal(); 369 std::vector<std::string> expectedErrMessagesException{ 370 "I2CException: Failed to close: bus /dev/i2c-1, addr 0x70"}; 371 EXPECT_CALL(journal, logError("Unable to close device vdd_reg")) 372 .Times(1); 373 EXPECT_CALL(journal, logError(expectedErrMessagesException)).Times(1); 374 EXPECT_CALL(errorLogging, 375 logI2CError(Entry::Level::Notice, Ref(journal), 376 "/dev/i2c-1", 0x70, 0)) 377 .Times(1); 378 379 // Create Device 380 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)}; 381 382 // Close Device 383 device.close(services); 384 } 385 } 386 387 TEST_F(DeviceTests, Configure) 388 { 389 // Test where device is not present 390 { 391 // Create mock services. No logging should occur. 392 MockServices services{}; 393 MockJournal& journal = services.getMockJournal(); 394 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0); 395 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 396 397 // Create PresenceDetection. Indicates device is not present. 398 std::unique_ptr<PresenceDetection> presenceDetection{}; 399 { 400 auto action = std::make_unique<MockAction>(); 401 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false)); 402 std::vector<std::unique_ptr<Action>> actions{}; 403 actions.emplace_back(std::move(action)); 404 presenceDetection = 405 std::make_unique<PresenceDetection>(std::move(actions)); 406 } 407 408 // Create Configuration. Action inside it should not be executed. 409 std::unique_ptr<Configuration> configuration{}; 410 { 411 std::optional<double> volts{}; 412 auto action = std::make_unique<MockAction>(); 413 EXPECT_CALL(*action, execute).Times(0); 414 std::vector<std::unique_ptr<Action>> actions{}; 415 actions.emplace_back(std::move(action)); 416 configuration = 417 std::make_unique<Configuration>(volts, std::move(actions)); 418 } 419 420 // Create Device 421 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 422 Device device{"reg2", 423 true, 424 deviceInvPath, 425 std::move(i2cInterface), 426 std::move(presenceDetection), 427 std::move(configuration)}; 428 429 // Call configure(). Should do nothing. 430 device.configure(services, *system, *chassis); 431 } 432 433 // Test where Configuration and Rails were not specified in constructor 434 { 435 // Create mock services. No logging should occur. 436 MockServices services{}; 437 MockJournal& journal = services.getMockJournal(); 438 EXPECT_CALL(journal, logDebug(A<const std::string&>())).Times(0); 439 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 440 441 // Create Device 442 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 443 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)}; 444 445 // Call configure(). 446 device.configure(services, *system, *chassis); 447 } 448 449 // Test where Configuration and Rails were specified in constructor 450 { 451 std::vector<std::unique_ptr<Rail>> rails{}; 452 453 // Create mock services. Expect logDebug() to be called. 454 // For the Device and both Rails, should execute the Configuration 455 // and log a debug message. 456 MockServices services{}; 457 MockJournal& journal = services.getMockJournal(); 458 EXPECT_CALL(journal, logDebug("Configuring reg2")).Times(1); 459 EXPECT_CALL(journal, logDebug("Configuring vdd0: volts=1.300000")) 460 .Times(1); 461 EXPECT_CALL(journal, logDebug("Configuring vio0: volts=3.200000")) 462 .Times(1); 463 EXPECT_CALL(journal, logError(A<const std::string&>())).Times(0); 464 465 // Create Rail vdd0 466 { 467 // Create Configuration for Rail 468 std::optional<double> volts{1.3}; 469 auto action = std::make_unique<MockAction>(); 470 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 471 std::vector<std::unique_ptr<Action>> actions{}; 472 actions.emplace_back(std::move(action)); 473 auto configuration = 474 std::make_unique<Configuration>(volts, std::move(actions)); 475 476 // Create Rail 477 auto rail = 478 std::make_unique<Rail>("vdd0", std::move(configuration)); 479 rails.emplace_back(std::move(rail)); 480 } 481 482 // Create Rail vio0 483 { 484 // Create Configuration for Rail 485 std::optional<double> volts{3.2}; 486 auto action = std::make_unique<MockAction>(); 487 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 488 std::vector<std::unique_ptr<Action>> actions{}; 489 actions.emplace_back(std::move(action)); 490 auto configuration = 491 std::make_unique<Configuration>(volts, std::move(actions)); 492 493 // Create Rail 494 auto rail = 495 std::make_unique<Rail>("vio0", std::move(configuration)); 496 rails.emplace_back(std::move(rail)); 497 } 498 499 // Create Configuration for Device 500 std::optional<double> volts{}; 501 auto action = std::make_unique<MockAction>(); 502 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 503 std::vector<std::unique_ptr<Action>> actions{}; 504 actions.emplace_back(std::move(action)); 505 auto configuration = 506 std::make_unique<Configuration>(volts, std::move(actions)); 507 508 // Create Device 509 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 510 std::unique_ptr<PresenceDetection> presenceDetection{}; 511 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 512 Device device{"reg2", 513 true, 514 deviceInvPath, 515 std::move(i2cInterface), 516 std::move(presenceDetection), 517 std::move(configuration), 518 std::move(phaseFaultDetection), 519 std::move(rails)}; 520 521 // Call configure(). 522 device.configure(services, *system, *chassis); 523 } 524 } 525 526 TEST_F(DeviceTests, GetConfiguration) 527 { 528 // Test where Configuration was not specified in constructor 529 { 530 Device device{"vdd_reg", true, deviceInvPath, 531 std::move(createI2CInterface())}; 532 EXPECT_EQ(device.getConfiguration(), nullptr); 533 } 534 535 // Test where Configuration was specified in constructor 536 { 537 std::unique_ptr<PresenceDetection> presenceDetection{}; 538 539 // Create Configuration 540 std::optional<double> volts{3.2}; 541 std::vector<std::unique_ptr<Action>> actions{}; 542 actions.push_back(std::make_unique<MockAction>()); 543 actions.push_back(std::make_unique<MockAction>()); 544 auto configuration = 545 std::make_unique<Configuration>(volts, std::move(actions)); 546 547 // Create Device 548 Device device{"vdd_reg", 549 true, 550 deviceInvPath, 551 std::move(createI2CInterface()), 552 std::move(presenceDetection), 553 std::move(configuration)}; 554 EXPECT_NE(device.getConfiguration(), nullptr); 555 EXPECT_EQ(device.getConfiguration()->getVolts().has_value(), true); 556 EXPECT_EQ(device.getConfiguration()->getVolts().value(), 3.2); 557 EXPECT_EQ(device.getConfiguration()->getActions().size(), 2); 558 } 559 } 560 561 TEST_F(DeviceTests, GetFRU) 562 { 563 Device device{"vdd_reg", true, deviceInvPath, 564 std::move(createI2CInterface())}; 565 EXPECT_EQ(device.getFRU(), deviceInvPath); 566 } 567 568 TEST_F(DeviceTests, GetI2CInterface) 569 { 570 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 571 i2c::I2CInterface* i2cInterfacePtr = i2cInterface.get(); 572 Device device{"vdd_reg", true, deviceInvPath, std::move(i2cInterface)}; 573 EXPECT_EQ(&(device.getI2CInterface()), i2cInterfacePtr); 574 } 575 576 TEST_F(DeviceTests, GetID) 577 { 578 Device device{"vdd_reg", false, deviceInvPath, 579 std::move(createI2CInterface())}; 580 EXPECT_EQ(device.getID(), "vdd_reg"); 581 } 582 583 TEST_F(DeviceTests, GetPhaseFaultDetection) 584 { 585 // Test where PhaseFaultDetection was not specified in constructor 586 { 587 Device device{"vdd_reg", true, deviceInvPath, 588 std::move(createI2CInterface())}; 589 EXPECT_EQ(device.getPhaseFaultDetection(), nullptr); 590 } 591 592 // Test where PhaseFaultDetection was specified in constructor 593 { 594 // Create PhaseFaultDetection 595 std::vector<std::unique_ptr<Action>> actions{}; 596 actions.push_back(std::make_unique<MockAction>()); 597 auto phaseFaultDetection = 598 std::make_unique<PhaseFaultDetection>(std::move(actions)); 599 600 // Create Device 601 std::unique_ptr<PresenceDetection> presenceDetection{}; 602 std::unique_ptr<Configuration> configuration{}; 603 Device device{"vdd_reg", 604 false, 605 deviceInvPath, 606 std::move(createI2CInterface()), 607 std::move(presenceDetection), 608 std::move(configuration), 609 std::move(phaseFaultDetection)}; 610 EXPECT_NE(device.getPhaseFaultDetection(), nullptr); 611 EXPECT_EQ(device.getPhaseFaultDetection()->getActions().size(), 1); 612 } 613 } 614 615 TEST_F(DeviceTests, GetPresenceDetection) 616 { 617 // Test where PresenceDetection was not specified in constructor 618 { 619 Device device{"vdd_reg", true, deviceInvPath, 620 std::move(createI2CInterface())}; 621 EXPECT_EQ(device.getPresenceDetection(), nullptr); 622 } 623 624 // Test where PresenceDetection was specified in constructor 625 { 626 // Create PresenceDetection 627 std::vector<std::unique_ptr<Action>> actions{}; 628 actions.push_back(std::make_unique<MockAction>()); 629 auto presenceDetection = 630 std::make_unique<PresenceDetection>(std::move(actions)); 631 632 // Create Device 633 Device device{"vdd_reg", false, deviceInvPath, 634 std::move(createI2CInterface()), 635 std::move(presenceDetection)}; 636 EXPECT_NE(device.getPresenceDetection(), nullptr); 637 EXPECT_EQ(device.getPresenceDetection()->getActions().size(), 1); 638 } 639 } 640 641 TEST_F(DeviceTests, GetRails) 642 { 643 // Test where no rails were specified in constructor 644 { 645 Device device{"vdd_reg", true, deviceInvPath, 646 std::move(createI2CInterface())}; 647 EXPECT_EQ(device.getRails().size(), 0); 648 } 649 650 // Test where rails were specified in constructor 651 { 652 std::unique_ptr<PresenceDetection> presenceDetection{}; 653 std::unique_ptr<Configuration> configuration{}; 654 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 655 656 // Create vector of Rail objects 657 std::vector<std::unique_ptr<Rail>> rails{}; 658 rails.push_back(std::make_unique<Rail>("vdd0")); 659 rails.push_back(std::make_unique<Rail>("vdd1")); 660 661 // Create Device 662 Device device{"vdd_reg", 663 false, 664 deviceInvPath, 665 std::move(createI2CInterface()), 666 std::move(presenceDetection), 667 std::move(configuration), 668 std::move(phaseFaultDetection), 669 std::move(rails)}; 670 EXPECT_EQ(device.getRails().size(), 2); 671 EXPECT_EQ(device.getRails()[0]->getID(), "vdd0"); 672 EXPECT_EQ(device.getRails()[1]->getID(), "vdd1"); 673 } 674 } 675 676 TEST_F(DeviceTests, IsPresent) 677 { 678 // Test where PresenceDetection not specified in constructor 679 { 680 // Create Device 681 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 682 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)}; 683 684 // Create MockServices 685 MockServices services{}; 686 687 // Since no PresenceDetection defined, isPresent() should return true 688 EXPECT_TRUE(device.isPresent(services, *system, *chassis)); 689 } 690 691 // Test where PresenceDetection was specified in constructor: Is present 692 { 693 // Create PresenceDetection. Indicates device is present. 694 auto action = std::make_unique<MockAction>(); 695 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 696 std::vector<std::unique_ptr<Action>> actions{}; 697 actions.emplace_back(std::move(action)); 698 auto presenceDetection = 699 std::make_unique<PresenceDetection>(std::move(actions)); 700 701 // Create Device 702 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 703 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface), 704 std::move(presenceDetection)}; 705 706 // Create MockServices 707 MockServices services{}; 708 709 // PresenceDetection::execute() and isPresent() should return true 710 EXPECT_TRUE(device.isPresent(services, *system, *chassis)); 711 } 712 713 // Test where PresenceDetection was specified in constructor: Is not present 714 { 715 // Create PresenceDetection. Indicates device is not present. 716 auto action = std::make_unique<MockAction>(); 717 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false)); 718 std::vector<std::unique_ptr<Action>> actions{}; 719 actions.emplace_back(std::move(action)); 720 auto presenceDetection = 721 std::make_unique<PresenceDetection>(std::move(actions)); 722 723 // Create Device 724 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 725 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface), 726 std::move(presenceDetection)}; 727 728 // Create MockServices 729 MockServices services{}; 730 731 // PresenceDetection::execute() and isPresent() should return false 732 EXPECT_FALSE(device.isPresent(services, *system, *chassis)); 733 } 734 } 735 736 TEST_F(DeviceTests, IsRegulator) 737 { 738 Device device{"vdd_reg", false, deviceInvPath, 739 std::move(createI2CInterface())}; 740 EXPECT_EQ(device.isRegulator(), false); 741 } 742 743 TEST_F(DeviceTests, MonitorSensors) 744 { 745 // Test where device is not present 746 { 747 // Create mock services. No Sensors methods should be called. 748 MockServices services{}; 749 MockSensors& sensors = services.getMockSensors(); 750 EXPECT_CALL(sensors, startRail).Times(0); 751 EXPECT_CALL(sensors, setValue).Times(0); 752 EXPECT_CALL(sensors, endRail).Times(0); 753 754 // Create SensorMonitoring. Action inside it should not be executed. 755 std::unique_ptr<SensorMonitoring> sensorMonitoring{}; 756 { 757 auto action = std::make_unique<MockAction>(); 758 EXPECT_CALL(*action, execute).Times(0); 759 std::vector<std::unique_ptr<Action>> actions{}; 760 actions.emplace_back(std::move(action)); 761 sensorMonitoring = 762 std::make_unique<SensorMonitoring>(std::move(actions)); 763 } 764 765 // Create Rail 766 std::unique_ptr<Configuration> configuration{}; 767 auto rail = std::make_unique<Rail>("vddr1", std::move(configuration), 768 std::move(sensorMonitoring)); 769 770 // Create PresenceDetection. Indicates device is not present. 771 std::unique_ptr<PresenceDetection> presenceDetection{}; 772 { 773 auto action = std::make_unique<MockAction>(); 774 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false)); 775 std::vector<std::unique_ptr<Action>> actions{}; 776 actions.emplace_back(std::move(action)); 777 presenceDetection = 778 std::make_unique<PresenceDetection>(std::move(actions)); 779 } 780 781 // Create Device 782 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 783 std::unique_ptr<Configuration> deviceConfiguration{}; 784 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 785 std::vector<std::unique_ptr<Rail>> rails{}; 786 rails.emplace_back(std::move(rail)); 787 Device device{"reg2", 788 true, 789 deviceInvPath, 790 std::move(i2cInterface), 791 std::move(presenceDetection), 792 std::move(deviceConfiguration), 793 std::move(phaseFaultDetection), 794 std::move(rails)}; 795 796 // Call monitorSensors(). Should do nothing. 797 device.monitorSensors(services, *system, *chassis); 798 } 799 800 // Test where Rails were not specified in constructor 801 { 802 // Create mock services. No Sensors methods should be called. 803 MockServices services{}; 804 MockSensors& sensors = services.getMockSensors(); 805 EXPECT_CALL(sensors, startRail).Times(0); 806 EXPECT_CALL(sensors, setValue).Times(0); 807 EXPECT_CALL(sensors, endRail).Times(0); 808 809 // Create Device 810 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 811 Device device{"reg2", true, deviceInvPath, std::move(i2cInterface)}; 812 813 // Call monitorSensors(). Should do nothing. 814 device.monitorSensors(services, *system, *chassis); 815 } 816 817 // Test where Rails were specified in constructor 818 { 819 // Create mock services. Set Sensors service expectations. 820 MockServices services{}; 821 MockSensors& sensors = services.getMockSensors(); 822 EXPECT_CALL(sensors, startRail("vdd0", deviceInvPath, chassisInvPath)) 823 .Times(1); 824 EXPECT_CALL(sensors, startRail("vio0", deviceInvPath, chassisInvPath)) 825 .Times(1); 826 EXPECT_CALL(sensors, setValue).Times(0); 827 EXPECT_CALL(sensors, endRail(false)).Times(2); 828 829 std::vector<std::unique_ptr<Rail>> rails{}; 830 831 // Create Rail vdd0 832 { 833 // Create SensorMonitoring for Rail 834 auto action = std::make_unique<MockAction>(); 835 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 836 std::vector<std::unique_ptr<Action>> actions{}; 837 actions.emplace_back(std::move(action)); 838 auto sensorMonitoring = 839 std::make_unique<SensorMonitoring>(std::move(actions)); 840 841 // Create Rail 842 std::unique_ptr<Configuration> configuration{}; 843 auto rail = std::make_unique<Rail>("vdd0", std::move(configuration), 844 std::move(sensorMonitoring)); 845 rails.emplace_back(std::move(rail)); 846 } 847 848 // Create Rail vio0 849 { 850 // Create SensorMonitoring for Rail 851 auto action = std::make_unique<MockAction>(); 852 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true)); 853 std::vector<std::unique_ptr<Action>> actions{}; 854 actions.emplace_back(std::move(action)); 855 auto sensorMonitoring = 856 std::make_unique<SensorMonitoring>(std::move(actions)); 857 858 // Create Rail 859 std::unique_ptr<Configuration> configuration{}; 860 auto rail = std::make_unique<Rail>("vio0", std::move(configuration), 861 std::move(sensorMonitoring)); 862 rails.emplace_back(std::move(rail)); 863 } 864 865 // Create Device that contains Rails 866 std::unique_ptr<i2c::I2CInterface> i2cInterface = createI2CInterface(); 867 std::unique_ptr<PresenceDetection> presenceDetection{}; 868 std::unique_ptr<Configuration> configuration{}; 869 std::unique_ptr<PhaseFaultDetection> phaseFaultDetection{}; 870 Device device{"reg2", 871 true, 872 deviceInvPath, 873 std::move(i2cInterface), 874 std::move(presenceDetection), 875 std::move(configuration), 876 std::move(phaseFaultDetection), 877 std::move(rails)}; 878 879 // Call monitorSensors(). Should monitor sensors in both rails. 880 device.monitorSensors(services, *system, *chassis); 881 } 882 } 883