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_vpd_action.hpp" 19 #include "id_map.hpp" 20 #include "mock_services.hpp" 21 #include "mock_vpd.hpp" 22 23 #include <exception> 24 #include <memory> 25 #include <stdexcept> 26 #include <string> 27 #include <utility> 28 29 #include <gmock/gmock.h> 30 #include <gtest/gtest.h> 31 32 using ::testing::Return; 33 using ::testing::Throw; 34 35 using namespace phosphor::power::regulators; 36 37 TEST(CompareVPDActionTests, Constructor) 38 { 39 // Value vector is not empty 40 { 41 std::vector<uint8_t> value{0x32, 0x44, 0x33, 0x35}; // "2D35" 42 CompareVPDAction action{ 43 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", 44 "CCIN", value}; 45 EXPECT_EQ( 46 action.getFRU(), 47 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); 48 EXPECT_EQ(action.getKeyword(), "CCIN"); 49 EXPECT_EQ(action.getValue(), value); 50 } 51 52 // Value vector is empty 53 { 54 std::vector<uint8_t> value{}; 55 CompareVPDAction action{ 56 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", 57 "CCIN", value}; 58 EXPECT_EQ( 59 action.getFRU(), 60 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); 61 EXPECT_EQ(action.getKeyword(), "CCIN"); 62 EXPECT_EQ(action.getValue(), value); 63 } 64 } 65 66 TEST(CompareVPDActionTests, Execute) 67 { 68 // Test where works: Actual VPD value is not empty 69 { 70 std::string fru{"/xyz/openbmc_project/inventory/system"}; 71 std::string keyword{"Model"}; 72 std::vector<uint8_t> abcdValue{0x41, 0x42, 0x43, 0x44}; 73 74 // Create MockServices object. VPD service will return "ABCD" as VPD 75 // value 3 times. 76 MockServices services{}; 77 MockVPD& vpd = services.getMockVPD(); 78 EXPECT_CALL(vpd, getValue(fru, keyword)) 79 .Times(3) 80 .WillRepeatedly(Return(abcdValue)); 81 82 IDMap idMap{}; 83 ActionEnvironment environment{idMap, "", services}; 84 85 // Test where returns true: actual value == expected value 86 { 87 CompareVPDAction action{fru, keyword, abcdValue}; 88 EXPECT_TRUE(action.execute(environment)); 89 } 90 91 // Test where returns false: actual value != expected value 92 { 93 CompareVPDAction action{fru, keyword, 94 std::vector<uint8_t>{1, 2, 3, 4}}; 95 EXPECT_FALSE(action.execute(environment)); 96 } 97 98 // Test where returns false: expected value is empty 99 { 100 CompareVPDAction action{fru, keyword, std::vector<uint8_t>{}}; 101 EXPECT_FALSE(action.execute(environment)); 102 } 103 } 104 105 // Test where works: Actual VPD value is empty 106 { 107 std::string fru{"/xyz/openbmc_project/inventory/system"}; 108 std::string keyword{"Model"}; 109 std::vector<uint8_t> emptyValue{}; 110 111 // Create MockServices object. VPD service will return empty VPD value 112 // 2 times. 113 MockServices services{}; 114 MockVPD& vpd = services.getMockVPD(); 115 EXPECT_CALL(vpd, getValue(fru, keyword)) 116 .Times(2) 117 .WillRepeatedly(Return(emptyValue)); 118 119 IDMap idMap{}; 120 ActionEnvironment environment{idMap, "", services}; 121 122 // Test where returns true: actual value == expected value 123 { 124 CompareVPDAction action{fru, keyword, emptyValue}; 125 EXPECT_TRUE(action.execute(environment)); 126 } 127 128 // Test where returns false: actual value != expected value 129 { 130 CompareVPDAction action{fru, keyword, 131 std::vector<uint8_t>{1, 2, 3}}; 132 EXPECT_FALSE(action.execute(environment)); 133 } 134 } 135 136 // Test where fails: Exception thrown when trying to get actual VPD value 137 { 138 std::string fru{"/xyz/openbmc_project/inventory/system"}; 139 std::string keyword{"Model"}; 140 141 // Create MockServices object. VPD service will throw an exception. 142 MockServices services{}; 143 MockVPD& vpd = services.getMockVPD(); 144 EXPECT_CALL(vpd, getValue(fru, keyword)) 145 .Times(1) 146 .WillOnce( 147 Throw(std::runtime_error{"D-Bus error: Invalid object path"})); 148 149 IDMap idMap{}; 150 ActionEnvironment environment{idMap, "", services}; 151 152 try 153 { 154 CompareVPDAction action{fru, keyword, 155 std::vector<uint8_t>{1, 2, 3}}; 156 action.execute(environment); 157 ADD_FAILURE() << "Should not have reached this line."; 158 } 159 catch (const ActionError& e) 160 { 161 EXPECT_STREQ(e.what(), 162 "ActionError: compare_vpd: { fru: " 163 "/xyz/openbmc_project/inventory/system, " 164 "keyword: Model, value: [ 0x1, 0x2, 0x3 ] }"); 165 try 166 { 167 // Re-throw inner exception 168 std::rethrow_if_nested(e); 169 ADD_FAILURE() << "Should not have reached this line."; 170 } 171 catch (const std::runtime_error& re) 172 { 173 EXPECT_STREQ(re.what(), "D-Bus error: Invalid object path"); 174 } 175 catch (...) 176 { 177 ADD_FAILURE() << "Should not have caught exception."; 178 } 179 } 180 catch (...) 181 { 182 ADD_FAILURE() << "Should not have caught exception."; 183 } 184 } 185 } 186 187 TEST(CompareVPDActionTests, GetFRU) 188 { 189 CompareVPDAction action{ 190 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", 191 std::vector<uint8_t>{1, 2, 3, 4}}; 192 EXPECT_EQ(action.getFRU(), 193 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); 194 } 195 196 TEST(CompareVPDActionTests, GetKeyword) 197 { 198 CompareVPDAction action{ 199 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", 200 std::vector<uint8_t>{1, 2, 3, 4}}; 201 EXPECT_EQ(action.getKeyword(), "CCIN"); 202 } 203 204 TEST(CompareVPDActionTests, GetValue) 205 { 206 CompareVPDAction action{ 207 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", 208 std::vector<uint8_t>{1, 2, 3, 4}}; 209 EXPECT_EQ(action.getValue(), (std::vector<uint8_t>{0x1, 0x2, 0x3, 0x4})); 210 } 211 212 TEST(CompareVPDActionTests, ToString) 213 { 214 // Test where value vector is not empty 215 { 216 CompareVPDAction action{ 217 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", 218 "CCIN", std::vector<uint8_t>{0x01, 0xA3, 0x0, 0xFF}}; 219 EXPECT_EQ(action.toString(), "compare_vpd: { fru: " 220 "/xyz/openbmc_project/inventory/system/" 221 "chassis/disk_backplane, keyword: " 222 "CCIN, value: [ 0x1, 0xA3, 0x0, 0xFF ] }"); 223 } 224 225 // Test where value vector is empty 226 { 227 CompareVPDAction action{ 228 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", 229 "CCIN", std::vector<uint8_t>{}}; 230 EXPECT_EQ(action.toString(), "compare_vpd: { fru: " 231 "/xyz/openbmc_project/inventory/system/" 232 "chassis/disk_backplane, keyword: " 233 "CCIN, value: [ ] }"); 234 } 235 } 236