| /** |
| * Copyright © 2020 IBM Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| #include "action_environment.hpp" |
| #include "action_error.hpp" |
| #include "compare_vpd_action.hpp" |
| #include "id_map.hpp" |
| #include "mock_services.hpp" |
| #include "mock_vpd.hpp" |
| |
| #include <exception> |
| #include <memory> |
| #include <stdexcept> |
| #include <string> |
| #include <utility> |
| |
| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| |
| using ::testing::Return; |
| using ::testing::Throw; |
| |
| using namespace phosphor::power::regulators; |
| |
| TEST(CompareVPDActionTests, Constructor) |
| { |
| // Value vector is not empty |
| { |
| std::vector<uint8_t> value{0x32, 0x44, 0x33, 0x35}; // "2D35" |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", |
| "CCIN", value}; |
| EXPECT_EQ( |
| action.getFRU(), |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); |
| EXPECT_EQ(action.getKeyword(), "CCIN"); |
| EXPECT_EQ(action.getValue(), value); |
| } |
| |
| // Value vector is empty |
| { |
| std::vector<uint8_t> value{}; |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", |
| "CCIN", value}; |
| EXPECT_EQ( |
| action.getFRU(), |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); |
| EXPECT_EQ(action.getKeyword(), "CCIN"); |
| EXPECT_EQ(action.getValue(), value); |
| } |
| } |
| |
| TEST(CompareVPDActionTests, Execute) |
| { |
| // Test where works: Actual VPD value is not empty |
| { |
| std::string fru{"/xyz/openbmc_project/inventory/system"}; |
| std::string keyword{"Model"}; |
| std::vector<uint8_t> abcdValue{0x41, 0x42, 0x43, 0x44}; |
| |
| // Create MockServices object. VPD service will return "ABCD" as VPD |
| // value 3 times. |
| MockServices services{}; |
| MockVPD& vpd = services.getMockVPD(); |
| EXPECT_CALL(vpd, getValue(fru, keyword)) |
| .Times(3) |
| .WillRepeatedly(Return(abcdValue)); |
| |
| IDMap idMap{}; |
| ActionEnvironment environment{idMap, "", services}; |
| |
| // Test where returns true: actual value == expected value |
| { |
| CompareVPDAction action{fru, keyword, abcdValue}; |
| EXPECT_TRUE(action.execute(environment)); |
| } |
| |
| // Test where returns false: actual value != expected value |
| { |
| CompareVPDAction action{fru, keyword, |
| std::vector<uint8_t>{1, 2, 3, 4}}; |
| EXPECT_FALSE(action.execute(environment)); |
| } |
| |
| // Test where returns false: expected value is empty |
| { |
| CompareVPDAction action{fru, keyword, std::vector<uint8_t>{}}; |
| EXPECT_FALSE(action.execute(environment)); |
| } |
| } |
| |
| // Test where works: Actual VPD value is empty |
| { |
| std::string fru{"/xyz/openbmc_project/inventory/system"}; |
| std::string keyword{"Model"}; |
| std::vector<uint8_t> emptyValue{}; |
| |
| // Create MockServices object. VPD service will return empty VPD value |
| // 2 times. |
| MockServices services{}; |
| MockVPD& vpd = services.getMockVPD(); |
| EXPECT_CALL(vpd, getValue(fru, keyword)) |
| .Times(2) |
| .WillRepeatedly(Return(emptyValue)); |
| |
| IDMap idMap{}; |
| ActionEnvironment environment{idMap, "", services}; |
| |
| // Test where returns true: actual value == expected value |
| { |
| CompareVPDAction action{fru, keyword, emptyValue}; |
| EXPECT_TRUE(action.execute(environment)); |
| } |
| |
| // Test where returns false: actual value != expected value |
| { |
| CompareVPDAction action{fru, keyword, |
| std::vector<uint8_t>{1, 2, 3}}; |
| EXPECT_FALSE(action.execute(environment)); |
| } |
| } |
| |
| // Test where fails: Exception thrown when trying to get actual VPD value |
| { |
| std::string fru{"/xyz/openbmc_project/inventory/system"}; |
| std::string keyword{"Model"}; |
| |
| // Create MockServices object. VPD service will throw an exception. |
| MockServices services{}; |
| MockVPD& vpd = services.getMockVPD(); |
| EXPECT_CALL(vpd, getValue(fru, keyword)) |
| .Times(1) |
| .WillOnce( |
| Throw(std::runtime_error{"D-Bus error: Invalid object path"})); |
| |
| IDMap idMap{}; |
| ActionEnvironment environment{idMap, "", services}; |
| |
| try |
| { |
| CompareVPDAction action{fru, keyword, |
| std::vector<uint8_t>{1, 2, 3}}; |
| action.execute(environment); |
| ADD_FAILURE() << "Should not have reached this line."; |
| } |
| catch (const ActionError& e) |
| { |
| EXPECT_STREQ(e.what(), |
| "ActionError: compare_vpd: { fru: " |
| "/xyz/openbmc_project/inventory/system, " |
| "keyword: Model, value: [ 0x1, 0x2, 0x3 ] }"); |
| try |
| { |
| // Re-throw inner exception |
| std::rethrow_if_nested(e); |
| ADD_FAILURE() << "Should not have reached this line."; |
| } |
| catch (const std::runtime_error& re) |
| { |
| EXPECT_STREQ(re.what(), "D-Bus error: Invalid object path"); |
| } |
| catch (...) |
| { |
| ADD_FAILURE() << "Should not have caught exception."; |
| } |
| } |
| catch (...) |
| { |
| ADD_FAILURE() << "Should not have caught exception."; |
| } |
| } |
| } |
| |
| TEST(CompareVPDActionTests, GetFRU) |
| { |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", |
| std::vector<uint8_t>{1, 2, 3, 4}}; |
| EXPECT_EQ(action.getFRU(), |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane"); |
| } |
| |
| TEST(CompareVPDActionTests, GetKeyword) |
| { |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", |
| std::vector<uint8_t>{1, 2, 3, 4}}; |
| EXPECT_EQ(action.getKeyword(), "CCIN"); |
| } |
| |
| TEST(CompareVPDActionTests, GetValue) |
| { |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", "CCIN", |
| std::vector<uint8_t>{1, 2, 3, 4}}; |
| EXPECT_EQ(action.getValue(), (std::vector<uint8_t>{0x1, 0x2, 0x3, 0x4})); |
| } |
| |
| TEST(CompareVPDActionTests, ToString) |
| { |
| // Test where value vector is not empty |
| { |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", |
| "CCIN", std::vector<uint8_t>{0x01, 0xA3, 0x0, 0xFF}}; |
| EXPECT_EQ(action.toString(), "compare_vpd: { fru: " |
| "/xyz/openbmc_project/inventory/system/" |
| "chassis/disk_backplane, keyword: " |
| "CCIN, value: [ 0x1, 0xA3, 0x0, 0xFF ] }"); |
| } |
| |
| // Test where value vector is empty |
| { |
| CompareVPDAction action{ |
| "/xyz/openbmc_project/inventory/system/chassis/disk_backplane", |
| "CCIN", std::vector<uint8_t>{}}; |
| EXPECT_EQ(action.toString(), "compare_vpd: { fru: " |
| "/xyz/openbmc_project/inventory/system/" |
| "chassis/disk_backplane, keyword: " |
| "CCIN, value: [ ] }"); |
| } |
| } |