blob: cea1bd2ef08f1c71a6fb88f1dfb89e9b2e4019ea [file] [log] [blame]
Shawn McCarneyc69a2752019-10-30 17:37:30 -05001/**
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"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060018#include "i2c_interface.hpp"
Shawn McCarneyc69a2752019-10-30 17:37:30 -050019#include "id_map.hpp"
Bob King73eacee2020-10-23 13:58:02 +080020#include "mock_services.hpp"
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060021#include "mocked_i2c_interface.hpp"
Shawn McCarney421128e2021-08-25 10:00:59 -050022#include "phase_fault.hpp"
Shawn McCarneyc69a2752019-10-30 17:37:30 -050023#include "rule.hpp"
24
25#include <cstddef> // for size_t
26#include <exception>
Shawn McCarney2134ca62019-11-11 13:06:18 -060027#include <memory>
Shawn McCarneyc69a2752019-10-30 17:37:30 -050028#include <stdexcept>
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060029#include <utility>
Shawn McCarney2134ca62019-11-11 13:06:18 -060030#include <vector>
Shawn McCarneyc69a2752019-10-30 17:37:30 -050031
32#include <gtest/gtest.h>
33
34using namespace phosphor::power::regulators;
35
36TEST(ActionEnvironmentTests, Constructor)
37{
38 // Create IDMap
39 IDMap idMap{};
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060040
Bob King73eacee2020-10-23 13:58:02 +080041 // Create mock services.
42 MockServices services{};
43
Shawn McCarneyafb7fc32019-12-11 19:42:03 -060044 // Create Device and add to IDMap
45 std::unique_ptr<i2c::I2CInterface> i2cInterface =
46 i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
Bob Kinga76898f2020-10-13 15:08:33 +080047 Device reg1{
48 "regulator1", true,
49 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
50 std::move(i2cInterface)};
Shawn McCarneyc69a2752019-10-30 17:37:30 -050051 idMap.addDevice(reg1);
52
53 // Verify object state after constructor
54 try
55 {
Bob King73eacee2020-10-23 13:58:02 +080056 ActionEnvironment env{idMap, "regulator1", services};
Shawn McCarney421128e2021-08-25 10:00:59 -050057 EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
Shawn McCarneyc69a2752019-10-30 17:37:30 -050058 EXPECT_EQ(env.getDevice().getID(), "regulator1");
59 EXPECT_EQ(env.getDeviceID(), "regulator1");
Shawn McCarney421128e2021-08-25 10:00:59 -050060 EXPECT_EQ(env.getPhaseFaults().size(), 0);
Shawn McCarneyc69a2752019-10-30 17:37:30 -050061 EXPECT_EQ(env.getRuleDepth(), 0);
Shawn McCarney0fd07d72020-03-06 17:16:24 -060062 EXPECT_EQ(env.getVolts().has_value(), false);
Shawn McCarneyc69a2752019-10-30 17:37:30 -050063 }
64 catch (const std::exception& error)
65 {
66 ADD_FAILURE() << "Should not have caught exception.";
67 }
68}
69
Shawn McCarney421128e2021-08-25 10:00:59 -050070TEST(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
84TEST(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
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500108TEST(ActionEnvironmentTests, DecrementRuleDepth)
109{
110 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800111 MockServices services{};
112 ActionEnvironment env{idMap, "", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500113 EXPECT_EQ(env.getRuleDepth(), 0);
Shawn McCarney2134ca62019-11-11 13:06:18 -0600114 env.incrementRuleDepth("set_voltage_rule");
115 env.incrementRuleDepth("set_voltage_rule");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500116 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
Shawn McCarney421128e2021-08-25 10:00:59 -0500125TEST(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
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500141TEST(ActionEnvironmentTests, GetDevice)
142{
143 // Create IDMap
144 IDMap idMap{};
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600145
Bob King73eacee2020-10-23 13:58:02 +0800146 // Create mock services.
147 MockServices services{};
148
Shawn McCarneyafb7fc32019-12-11 19:42:03 -0600149 // Create Device and add to IDMap
150 std::unique_ptr<i2c::I2CInterface> i2cInterface =
151 i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
Bob Kinga76898f2020-10-13 15:08:33 +0800152 Device reg1{
153 "regulator1", true,
154 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
155 std::move(i2cInterface)};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500156 idMap.addDevice(reg1);
157
Bob King73eacee2020-10-23 13:58:02 +0800158 ActionEnvironment env{idMap, "regulator1", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500159
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, &reg1);
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
190TEST(ActionEnvironmentTests, GetDeviceID)
191{
192 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800193 MockServices services{};
194 ActionEnvironment env{idMap, "", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500195 EXPECT_EQ(env.getDeviceID(), "");
196 env.setDeviceID("regulator1");
197 EXPECT_EQ(env.getDeviceID(), "regulator1");
198}
199
Shawn McCarney421128e2021-08-25 10:00:59 -0500200TEST(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
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500214TEST(ActionEnvironmentTests, GetRule)
215{
216 // Create IDMap
217 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800218
219 // Create mock services.
220 MockServices services{};
221
Shawn McCarney9fc08e72019-11-07 13:18:55 -0600222 Rule setVoltageRule{"set_voltage_rule",
223 std::vector<std::unique_ptr<Action>>{}};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500224 idMap.addRule(setVoltageRule);
225
Bob King73eacee2020-10-23 13:58:02 +0800226 ActionEnvironment env{idMap, "", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500227
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
257TEST(ActionEnvironmentTests, GetRuleDepth)
258{
259 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800260 MockServices services{};
261 ActionEnvironment env{idMap, "", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500262 EXPECT_EQ(env.getRuleDepth(), 0);
Shawn McCarney2134ca62019-11-11 13:06:18 -0600263 env.incrementRuleDepth("set_voltage_rule");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500264 EXPECT_EQ(env.getRuleDepth(), 1);
Shawn McCarney2134ca62019-11-11 13:06:18 -0600265 env.incrementRuleDepth("set_voltage_rule");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500266 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
Bob King73eacee2020-10-23 13:58:02 +0800273TEST(ActionEnvironmentTests, GetServices)
274{
275 IDMap idMap{};
276 MockServices services{};
277 ActionEnvironment env{idMap, "", services};
278 EXPECT_EQ(&(env.getServices()), &services);
279}
280
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500281TEST(ActionEnvironmentTests, GetVolts)
282{
283 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800284 MockServices services{};
285 ActionEnvironment env{idMap, "", services};
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600286 EXPECT_EQ(env.getVolts().has_value(), false);
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500287 env.setVolts(1.31);
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600288 EXPECT_EQ(env.getVolts().has_value(), true);
289 EXPECT_EQ(env.getVolts().value(), 1.31);
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500290}
291
292TEST(ActionEnvironmentTests, IncrementRuleDepth)
293{
294 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800295 MockServices services{};
296 ActionEnvironment env{idMap, "", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500297 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 {
Shawn McCarney2134ca62019-11-11 13:06:18 -0600304 env.incrementRuleDepth("set_voltage_rule");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500305 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 {
Shawn McCarney2134ca62019-11-11 13:06:18 -0600316 env.incrementRuleDepth("set_voltage_rule");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500317 }
318 catch (const std::runtime_error& r_error)
319 {
Shawn McCarney2134ca62019-11-11 13:06:18 -0600320 EXPECT_STREQ(r_error.what(),
321 "Maximum rule depth exceeded by rule set_voltage_rule.");
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500322 }
323 catch (const std::exception& error)
324 {
325 ADD_FAILURE() << "Should not have caught exception.";
326 }
327}
328
329TEST(ActionEnvironmentTests, SetDeviceID)
330{
331 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800332 MockServices services{};
333 ActionEnvironment env{idMap, "regulator1", services};
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500334 EXPECT_EQ(env.getDeviceID(), "regulator1");
335 env.setDeviceID("regulator2");
336 EXPECT_EQ(env.getDeviceID(), "regulator2");
337}
338
339TEST(ActionEnvironmentTests, SetVolts)
340{
341 try
342 {
343 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800344 MockServices services{};
345 ActionEnvironment env{idMap, "", services};
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600346 EXPECT_EQ(env.getVolts().has_value(), false);
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500347 env.setVolts(2.35);
Shawn McCarney0fd07d72020-03-06 17:16:24 -0600348 EXPECT_EQ(env.getVolts().has_value(), true);
349 EXPECT_EQ(env.getVolts().value(), 2.35);
Shawn McCarneyc69a2752019-10-30 17:37:30 -0500350 }
351 catch (const std::exception& error)
352 {
353 ADD_FAILURE() << "Should not have caught exception.";
354 }
355}