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 "compare_presence_action.hpp" 19 #include "device.hpp" 20 #include "i2c_interface.hpp" 21 #include "id_map.hpp" 22 #include "mock_action.hpp" 23 #include "mock_presence_service.hpp" 24 #include "mock_services.hpp" 25 #include "mocked_i2c_interface.hpp" 26 27 #include <exception> 28 #include <memory> 29 #include <stdexcept> 30 #include <utility> 31 32 #include <gmock/gmock.h> 33 #include <gtest/gtest.h> 34 35 using namespace phosphor::power::regulators; 36 37 using ::testing::Return; 38 using ::testing::Throw; 39 40 TEST(ComparePresenceActionTests, Constructor) 41 { 42 ComparePresenceAction action{ 43 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu3", true}; 44 EXPECT_EQ(action.getFRU(), 45 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu3"); 46 EXPECT_EQ(action.getValue(), true); 47 } 48 49 TEST(ComparePresenceActionTests, Execute) 50 { 51 // Test where works: actual value is true. 52 try 53 { 54 // Create mock I2CInterface 55 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 56 std::make_unique<i2c::MockedI2CInterface>(); 57 58 // Create Device, IDMap, MockServices and ActionEnvironment 59 // Actual value isPresent() is true 60 Device device{ 61 "reg1", true, 62 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 63 std::move(i2cInterface)}; 64 IDMap idMap{}; 65 idMap.addDevice(device); 66 MockServices services{}; 67 MockPresenceService& presenceService = 68 services.getMockPresenceService(); 69 EXPECT_CALL(presenceService, 70 isPresent("/xyz/openbmc_project/inventory/system/chassis/" 71 "motherboard/cpu2")) 72 .Times(2) 73 .WillRepeatedly(Return(true)); 74 ActionEnvironment env{idMap, "reg1", services}; 75 76 // Test where works: expected value is true, return value is true. 77 { 78 ComparePresenceAction action{"/xyz/openbmc_project/inventory/" 79 "system/chassis/motherboard/cpu2", 80 true}; 81 EXPECT_EQ(action.execute(env), true); 82 } 83 84 // Test where works: expected value is false, return value is false. 85 { 86 ComparePresenceAction action{"/xyz/openbmc_project/inventory/" 87 "system/chassis/motherboard/cpu2", 88 false}; 89 EXPECT_EQ(action.execute(env), false); 90 } 91 } 92 catch (...) 93 { 94 ADD_FAILURE() << "Should not have caught exception."; 95 } 96 97 // Test where actual value is false. 98 try 99 { 100 // Create mock I2CInterface 101 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 102 std::make_unique<i2c::MockedI2CInterface>(); 103 104 // Create Device, IDMap, MockServices and ActionEnvironment 105 // Actual value isPresent() is false 106 Device device{ 107 "reg1", true, 108 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 109 std::move(i2cInterface)}; 110 IDMap idMap{}; 111 idMap.addDevice(device); 112 MockServices services{}; 113 MockPresenceService& presenceService = 114 services.getMockPresenceService(); 115 EXPECT_CALL(presenceService, 116 isPresent("/xyz/openbmc_project/inventory/system/chassis/" 117 "motherboard/cpu2")) 118 .Times(2) 119 .WillRepeatedly(Return(false)); 120 ActionEnvironment env{idMap, "reg1", services}; 121 122 // Test where works: expected value is true, return value is false. 123 { 124 ComparePresenceAction action{"/xyz/openbmc_project/inventory/" 125 "system/chassis/motherboard/cpu2", 126 true}; 127 EXPECT_EQ(action.execute(env), false); 128 } 129 130 // Test where works: expected value is false, return value is true. 131 { 132 ComparePresenceAction action{"/xyz/openbmc_project/inventory/" 133 "system/chassis/motherboard/cpu2", 134 false}; 135 EXPECT_EQ(action.execute(env), true); 136 } 137 } 138 catch (...) 139 { 140 ADD_FAILURE() << "Should not have caught exception."; 141 } 142 143 // Test where fails. Reading presence fails. 144 try 145 { 146 // Create mock I2CInterface 147 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface = 148 std::make_unique<i2c::MockedI2CInterface>(); 149 150 // Create Device, IDMap, MockServices and ActionEnvironment 151 // PresenceService cannot get the presence 152 Device device{ 153 "reg1", true, 154 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1", 155 std::move(i2cInterface)}; 156 IDMap idMap{}; 157 idMap.addDevice(device); 158 MockServices services{}; 159 MockPresenceService& presenceService = 160 services.getMockPresenceService(); 161 EXPECT_CALL(presenceService, 162 isPresent("/xyz/openbmc_project/inventory/system/chassis/" 163 "motherboard/cpu2")) 164 .Times(1) 165 .WillOnce(Throw(std::runtime_error( 166 "PresenceService cannot get the presence."))); 167 168 ActionEnvironment env{idMap, "reg1", services}; 169 170 ComparePresenceAction action{"/xyz/openbmc_project/inventory/" 171 "system/chassis/motherboard/cpu2", 172 true}; 173 action.execute(env); 174 ADD_FAILURE() << "Should not have reached this line."; 175 } 176 catch (const ActionError& e) 177 { 178 EXPECT_STREQ(e.what(), "ActionError: compare_presence: { fru: " 179 "/xyz/openbmc_project/inventory/system/chassis/" 180 "motherboard/cpu2, value: true }"); 181 try 182 { 183 // Re-throw inner exception from MockPresenceService. 184 std::rethrow_if_nested(e); 185 ADD_FAILURE() << "Should not have reached this line."; 186 } 187 catch (const std::runtime_error& r_error) 188 { 189 EXPECT_STREQ(r_error.what(), 190 "PresenceService cannot get the presence."); 191 } 192 catch (...) 193 { 194 ADD_FAILURE() << "Should not have caught exception."; 195 } 196 } 197 catch (...) 198 { 199 ADD_FAILURE() << "Should not have caught exception."; 200 } 201 } 202 203 TEST(ComparePresenceActionTests, GetFRU) 204 { 205 ComparePresenceAction action{ 206 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2", true}; 207 EXPECT_EQ(action.getFRU(), 208 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"); 209 } 210 211 TEST(ComparePresenceActionTests, GetValue) 212 { 213 ComparePresenceAction action{ 214 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu3", 215 false}; 216 EXPECT_EQ(action.getValue(), false); 217 } 218 219 TEST(ComparePresenceActionTests, ToString) 220 { 221 ComparePresenceAction action{ 222 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2", true}; 223 EXPECT_EQ(action.toString(), 224 "compare_presence: { fru: " 225 "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2, " 226 "value: true }"); 227 } 228