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
TEST(CompareVPDActionTests,Constructor)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
TEST(CompareVPDActionTests,Execute)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
TEST(CompareVPDActionTests,GetFRU)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
TEST(CompareVPDActionTests,GetKeyword)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
TEST(CompareVPDActionTests,GetValue)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
TEST(CompareVPDActionTests,ToString)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(),
220 "compare_vpd: { fru: "
221 "/xyz/openbmc_project/inventory/system/"
222 "chassis/disk_backplane, keyword: "
223 "CCIN, value: [ 0x1, 0xA3, 0x0, 0xFF ] }");
224 }
225
226 // Test where value vector is empty
227 {
228 CompareVPDAction action{
229 "/xyz/openbmc_project/inventory/system/chassis/disk_backplane",
230 "CCIN", std::vector<uint8_t>{}};
231 EXPECT_EQ(action.toString(),
232 "compare_vpd: { fru: "
233 "/xyz/openbmc_project/inventory/system/"
234 "chassis/disk_backplane, keyword: "
235 "CCIN, value: [ ] }");
236 }
237 }
238