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_environment.hpp"
17 #include "device.hpp"
18 #include "i2c_interface.hpp"
19 #include "id_map.hpp"
20 #include "mock_services.hpp"
21 #include "mocked_i2c_interface.hpp"
22 #include "phase_fault.hpp"
23 #include "rule.hpp"
24
25 #include <cstddef> // for size_t
26 #include <exception>
27 #include <memory>
28 #include <stdexcept>
29 #include <utility>
30 #include <vector>
31
32 #include <gtest/gtest.h>
33
34 using namespace phosphor::power::regulators;
35
TEST(ActionEnvironmentTests,Constructor)36 TEST(ActionEnvironmentTests, Constructor)
37 {
38 // Create IDMap
39 IDMap idMap{};
40
41 // Create mock services.
42 MockServices services{};
43
44 // Create Device and add to IDMap
45 std::unique_ptr<i2c::I2CInterface> i2cInterface =
46 i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
47 Device reg1{
48 "regulator1", true,
49 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
50 std::move(i2cInterface)};
51 idMap.addDevice(reg1);
52
53 // Verify object state after constructor
54 try
55 {
56 ActionEnvironment env{idMap, "regulator1", services};
57 EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
58 EXPECT_EQ(env.getDevice().getID(), "regulator1");
59 EXPECT_EQ(env.getDeviceID(), "regulator1");
60 EXPECT_EQ(env.getPhaseFaults().size(), 0);
61 EXPECT_EQ(env.getRuleDepth(), 0);
62 EXPECT_EQ(env.getVolts().has_value(), false);
63 }
64 catch (const std::exception& error)
65 {
66 ADD_FAILURE() << "Should not have caught exception.";
67 }
68 }
69
TEST(ActionEnvironmentTests,AddAdditionalErrorData)70 TEST(ActionEnvironmentTests, AddAdditionalErrorData)
71 {
72 IDMap idMap{};
73 MockServices services{};
74 ActionEnvironment env{idMap, "", services};
75 EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
76
77 env.addAdditionalErrorData("foo", "foo_value");
78 env.addAdditionalErrorData("bar", "bar_value");
79 EXPECT_EQ(env.getAdditionalErrorData().size(), 2);
80 EXPECT_EQ(env.getAdditionalErrorData().at("foo"), "foo_value");
81 EXPECT_EQ(env.getAdditionalErrorData().at("bar"), "bar_value");
82 }
83
TEST(ActionEnvironmentTests,AddPhaseFault)84 TEST(ActionEnvironmentTests, AddPhaseFault)
85 {
86 IDMap idMap{};
87 MockServices services{};
88 ActionEnvironment env{idMap, "", services};
89 EXPECT_EQ(env.getPhaseFaults().size(), 0);
90
91 // Add N phase fault
92 env.addPhaseFault(PhaseFaultType::n);
93 EXPECT_EQ(env.getPhaseFaults().size(), 1);
94 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
95 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 0);
96
97 // Add N+1 phase fault
98 env.addPhaseFault(PhaseFaultType::n_plus_1);
99 EXPECT_EQ(env.getPhaseFaults().size(), 2);
100 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
101 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 1);
102
103 // Add N+1 phase fault again; should be ignored since stored in a std::set
104 env.addPhaseFault(PhaseFaultType::n_plus_1);
105 EXPECT_EQ(env.getPhaseFaults().size(), 2);
106 }
107
TEST(ActionEnvironmentTests,DecrementRuleDepth)108 TEST(ActionEnvironmentTests, DecrementRuleDepth)
109 {
110 IDMap idMap{};
111 MockServices services{};
112 ActionEnvironment env{idMap, "", services};
113 EXPECT_EQ(env.getRuleDepth(), 0);
114 env.incrementRuleDepth("set_voltage_rule");
115 env.incrementRuleDepth("set_voltage_rule");
116 EXPECT_EQ(env.getRuleDepth(), 2);
117 env.decrementRuleDepth();
118 EXPECT_EQ(env.getRuleDepth(), 1);
119 env.decrementRuleDepth();
120 EXPECT_EQ(env.getRuleDepth(), 0);
121 env.decrementRuleDepth();
122 EXPECT_EQ(env.getRuleDepth(), 0);
123 }
124
TEST(ActionEnvironmentTests,GetAdditionalErrorData)125 TEST(ActionEnvironmentTests, GetAdditionalErrorData)
126 {
127 IDMap idMap{};
128 MockServices services{};
129 ActionEnvironment env{idMap, "", services};
130 EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
131
132 env.addAdditionalErrorData("foo", "foo_value");
133 EXPECT_EQ(env.getAdditionalErrorData().size(), 1);
134 EXPECT_EQ(env.getAdditionalErrorData().at("foo"), "foo_value");
135
136 env.addAdditionalErrorData("bar", "bar_value");
137 EXPECT_EQ(env.getAdditionalErrorData().size(), 2);
138 EXPECT_EQ(env.getAdditionalErrorData().at("bar"), "bar_value");
139 }
140
TEST(ActionEnvironmentTests,GetDevice)141 TEST(ActionEnvironmentTests, GetDevice)
142 {
143 // Create IDMap
144 IDMap idMap{};
145
146 // Create mock services.
147 MockServices services{};
148
149 // Create Device and add to IDMap
150 std::unique_ptr<i2c::I2CInterface> i2cInterface =
151 i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
152 Device reg1{
153 "regulator1", true,
154 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
155 std::move(i2cInterface)};
156 idMap.addDevice(reg1);
157
158 ActionEnvironment env{idMap, "regulator1", services};
159
160 // Test where current device ID is in the IDMap
161 try
162 {
163 Device& device = env.getDevice();
164 EXPECT_EQ(device.getID(), "regulator1");
165 EXPECT_EQ(&device, ®1);
166 }
167 catch (const std::exception& error)
168 {
169 ADD_FAILURE() << "Should not have caught exception.";
170 }
171
172 // Test where current device ID is not in the IDMap
173 env.setDeviceID("regulator2");
174 try
175 {
176 env.getDevice();
177 ADD_FAILURE() << "Should not have reached this line.";
178 }
179 catch (const std::invalid_argument& ia_error)
180 {
181 EXPECT_STREQ(ia_error.what(),
182 "Unable to find device with ID \"regulator2\"");
183 }
184 catch (const std::exception& error)
185 {
186 ADD_FAILURE() << "Should not have caught exception.";
187 }
188 }
189
TEST(ActionEnvironmentTests,GetDeviceID)190 TEST(ActionEnvironmentTests, GetDeviceID)
191 {
192 IDMap idMap{};
193 MockServices services{};
194 ActionEnvironment env{idMap, "", services};
195 EXPECT_EQ(env.getDeviceID(), "");
196 env.setDeviceID("regulator1");
197 EXPECT_EQ(env.getDeviceID(), "regulator1");
198 }
199
TEST(ActionEnvironmentTests,GetPhaseFaults)200 TEST(ActionEnvironmentTests, GetPhaseFaults)
201 {
202 IDMap idMap{};
203 MockServices services{};
204 ActionEnvironment env{idMap, "", services};
205 EXPECT_EQ(env.getPhaseFaults().size(), 0);
206
207 env.addPhaseFault(PhaseFaultType::n);
208 env.addPhaseFault(PhaseFaultType::n_plus_1);
209 EXPECT_EQ(env.getPhaseFaults().size(), 2);
210 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
211 EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 1);
212 }
213
TEST(ActionEnvironmentTests,GetRule)214 TEST(ActionEnvironmentTests, GetRule)
215 {
216 // Create IDMap
217 IDMap idMap{};
218
219 // Create mock services.
220 MockServices services{};
221
222 Rule setVoltageRule{"set_voltage_rule",
223 std::vector<std::unique_ptr<Action>>{}};
224 idMap.addRule(setVoltageRule);
225
226 ActionEnvironment env{idMap, "", services};
227
228 // Test where rule ID is in the IDMap
229 try
230 {
231 Rule& rule = env.getRule("set_voltage_rule");
232 EXPECT_EQ(rule.getID(), "set_voltage_rule");
233 EXPECT_EQ(&rule, &setVoltageRule);
234 }
235 catch (const std::exception& error)
236 {
237 ADD_FAILURE() << "Should not have caught exception.";
238 }
239
240 // Test where rule ID is not in the IDMap
241 try
242 {
243 env.getRule("set_voltage_rule2");
244 ADD_FAILURE() << "Should not have reached this line.";
245 }
246 catch (const std::invalid_argument& ia_error)
247 {
248 EXPECT_STREQ(ia_error.what(),
249 "Unable to find rule with ID \"set_voltage_rule2\"");
250 }
251 catch (const std::exception& error)
252 {
253 ADD_FAILURE() << "Should not have caught exception.";
254 }
255 }
256
TEST(ActionEnvironmentTests,GetRuleDepth)257 TEST(ActionEnvironmentTests, GetRuleDepth)
258 {
259 IDMap idMap{};
260 MockServices services{};
261 ActionEnvironment env{idMap, "", services};
262 EXPECT_EQ(env.getRuleDepth(), 0);
263 env.incrementRuleDepth("set_voltage_rule");
264 EXPECT_EQ(env.getRuleDepth(), 1);
265 env.incrementRuleDepth("set_voltage_rule");
266 EXPECT_EQ(env.getRuleDepth(), 2);
267 env.decrementRuleDepth();
268 EXPECT_EQ(env.getRuleDepth(), 1);
269 env.decrementRuleDepth();
270 EXPECT_EQ(env.getRuleDepth(), 0);
271 }
272
TEST(ActionEnvironmentTests,GetServices)273 TEST(ActionEnvironmentTests, GetServices)
274 {
275 IDMap idMap{};
276 MockServices services{};
277 ActionEnvironment env{idMap, "", services};
278 EXPECT_EQ(&(env.getServices()), &services);
279 }
280
TEST(ActionEnvironmentTests,GetVolts)281 TEST(ActionEnvironmentTests, GetVolts)
282 {
283 IDMap idMap{};
284 MockServices services{};
285 ActionEnvironment env{idMap, "", services};
286 EXPECT_EQ(env.getVolts().has_value(), false);
287 env.setVolts(1.31);
288 EXPECT_EQ(env.getVolts().has_value(), true);
289 EXPECT_EQ(env.getVolts().value(), 1.31);
290 }
291
TEST(ActionEnvironmentTests,IncrementRuleDepth)292 TEST(ActionEnvironmentTests, IncrementRuleDepth)
293 {
294 IDMap idMap{};
295 MockServices services{};
296 ActionEnvironment env{idMap, "", services};
297 EXPECT_EQ(env.getRuleDepth(), 0);
298
299 // Test where rule depth has not exceeded maximum
300 try
301 {
302 for (size_t i = 1; i <= env.maxRuleDepth; ++i)
303 {
304 env.incrementRuleDepth("set_voltage_rule");
305 EXPECT_EQ(env.getRuleDepth(), i);
306 }
307 }
308 catch (const std::exception& error)
309 {
310 ADD_FAILURE() << "Should not have caught exception.";
311 }
312
313 // Test where rule depth has exceeded maximum
314 try
315 {
316 env.incrementRuleDepth("set_voltage_rule");
317 }
318 catch (const std::runtime_error& r_error)
319 {
320 EXPECT_STREQ(r_error.what(),
321 "Maximum rule depth exceeded by rule set_voltage_rule.");
322 }
323 catch (const std::exception& error)
324 {
325 ADD_FAILURE() << "Should not have caught exception.";
326 }
327 }
328
TEST(ActionEnvironmentTests,SetDeviceID)329 TEST(ActionEnvironmentTests, SetDeviceID)
330 {
331 IDMap idMap{};
332 MockServices services{};
333 ActionEnvironment env{idMap, "regulator1", services};
334 EXPECT_EQ(env.getDeviceID(), "regulator1");
335 env.setDeviceID("regulator2");
336 EXPECT_EQ(env.getDeviceID(), "regulator2");
337 }
338
TEST(ActionEnvironmentTests,SetVolts)339 TEST(ActionEnvironmentTests, SetVolts)
340 {
341 try
342 {
343 IDMap idMap{};
344 MockServices services{};
345 ActionEnvironment env{idMap, "", services};
346 EXPECT_EQ(env.getVolts().has_value(), false);
347 env.setVolts(2.35);
348 EXPECT_EQ(env.getVolts().has_value(), true);
349 EXPECT_EQ(env.getVolts().value(), 2.35);
350 }
351 catch (const std::exception& error)
352 {
353 ADD_FAILURE() << "Should not have caught exception.";
354 }
355 }
356