1c69a2750SShawn McCarney /**
2c69a2750SShawn McCarney  * Copyright © 2019 IBM Corporation
3c69a2750SShawn McCarney  *
4c69a2750SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
5c69a2750SShawn McCarney  * you may not use this file except in compliance with the License.
6c69a2750SShawn McCarney  * You may obtain a copy of the License at
7c69a2750SShawn McCarney  *
8c69a2750SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
9c69a2750SShawn McCarney  *
10c69a2750SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
11c69a2750SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
12c69a2750SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c69a2750SShawn McCarney  * See the License for the specific language governing permissions and
14c69a2750SShawn McCarney  * limitations under the License.
15c69a2750SShawn McCarney  */
16c69a2750SShawn McCarney #include "action_environment.hpp"
17c69a2750SShawn McCarney #include "device.hpp"
18afb7fc3fSShawn McCarney #include "i2c_interface.hpp"
19c69a2750SShawn McCarney #include "id_map.hpp"
2073eaceebSBob King #include "mock_services.hpp"
21afb7fc3fSShawn McCarney #include "mocked_i2c_interface.hpp"
22*421128efSShawn McCarney #include "phase_fault.hpp"
23c69a2750SShawn McCarney #include "rule.hpp"
24c69a2750SShawn McCarney 
25c69a2750SShawn McCarney #include <cstddef> // for size_t
26c69a2750SShawn McCarney #include <exception>
272134ca66SShawn McCarney #include <memory>
28c69a2750SShawn McCarney #include <stdexcept>
29afb7fc3fSShawn McCarney #include <utility>
302134ca66SShawn McCarney #include <vector>
31c69a2750SShawn McCarney 
32c69a2750SShawn McCarney #include <gtest/gtest.h>
33c69a2750SShawn McCarney 
34c69a2750SShawn McCarney using namespace phosphor::power::regulators;
35c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,Constructor)36c69a2750SShawn McCarney TEST(ActionEnvironmentTests, Constructor)
37c69a2750SShawn McCarney {
38c69a2750SShawn McCarney     // Create IDMap
39c69a2750SShawn McCarney     IDMap idMap{};
40afb7fc3fSShawn McCarney 
4173eaceebSBob King     // Create mock services.
4273eaceebSBob King     MockServices services{};
4373eaceebSBob King 
44afb7fc3fSShawn McCarney     // Create Device and add to IDMap
45afb7fc3fSShawn McCarney     std::unique_ptr<i2c::I2CInterface> i2cInterface =
46afb7fc3fSShawn McCarney         i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
47a76898f1SBob King     Device reg1{
48a76898f1SBob King         "regulator1", true,
49a76898f1SBob King         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
50afb7fc3fSShawn McCarney         std::move(i2cInterface)};
51c69a2750SShawn McCarney     idMap.addDevice(reg1);
52c69a2750SShawn McCarney 
53c69a2750SShawn McCarney     // Verify object state after constructor
54c69a2750SShawn McCarney     try
55c69a2750SShawn McCarney     {
5673eaceebSBob King         ActionEnvironment env{idMap, "regulator1", services};
57*421128efSShawn McCarney         EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
58c69a2750SShawn McCarney         EXPECT_EQ(env.getDevice().getID(), "regulator1");
59c69a2750SShawn McCarney         EXPECT_EQ(env.getDeviceID(), "regulator1");
60*421128efSShawn McCarney         EXPECT_EQ(env.getPhaseFaults().size(), 0);
61c69a2750SShawn McCarney         EXPECT_EQ(env.getRuleDepth(), 0);
620fd07d7dSShawn McCarney         EXPECT_EQ(env.getVolts().has_value(), false);
63c69a2750SShawn McCarney     }
64c69a2750SShawn McCarney     catch (const std::exception& error)
65c69a2750SShawn McCarney     {
66c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
67c69a2750SShawn McCarney     }
68c69a2750SShawn McCarney }
69c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,AddAdditionalErrorData)70*421128efSShawn McCarney TEST(ActionEnvironmentTests, AddAdditionalErrorData)
71*421128efSShawn McCarney {
72*421128efSShawn McCarney     IDMap idMap{};
73*421128efSShawn McCarney     MockServices services{};
74*421128efSShawn McCarney     ActionEnvironment env{idMap, "", services};
75*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
76*421128efSShawn McCarney 
77*421128efSShawn McCarney     env.addAdditionalErrorData("foo", "foo_value");
78*421128efSShawn McCarney     env.addAdditionalErrorData("bar", "bar_value");
79*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().size(), 2);
80*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().at("foo"), "foo_value");
81*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().at("bar"), "bar_value");
82*421128efSShawn McCarney }
83*421128efSShawn McCarney 
TEST(ActionEnvironmentTests,AddPhaseFault)84*421128efSShawn McCarney TEST(ActionEnvironmentTests, AddPhaseFault)
85*421128efSShawn McCarney {
86*421128efSShawn McCarney     IDMap idMap{};
87*421128efSShawn McCarney     MockServices services{};
88*421128efSShawn McCarney     ActionEnvironment env{idMap, "", services};
89*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 0);
90*421128efSShawn McCarney 
91*421128efSShawn McCarney     // Add N phase fault
92*421128efSShawn McCarney     env.addPhaseFault(PhaseFaultType::n);
93*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 1);
94*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
95*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 0);
96*421128efSShawn McCarney 
97*421128efSShawn McCarney     // Add N+1 phase fault
98*421128efSShawn McCarney     env.addPhaseFault(PhaseFaultType::n_plus_1);
99*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 2);
100*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
101*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 1);
102*421128efSShawn McCarney 
103*421128efSShawn McCarney     // Add N+1 phase fault again; should be ignored since stored in a std::set
104*421128efSShawn McCarney     env.addPhaseFault(PhaseFaultType::n_plus_1);
105*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 2);
106*421128efSShawn McCarney }
107*421128efSShawn McCarney 
TEST(ActionEnvironmentTests,DecrementRuleDepth)108c69a2750SShawn McCarney TEST(ActionEnvironmentTests, DecrementRuleDepth)
109c69a2750SShawn McCarney {
110c69a2750SShawn McCarney     IDMap idMap{};
11173eaceebSBob King     MockServices services{};
11273eaceebSBob King     ActionEnvironment env{idMap, "", services};
113c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
1142134ca66SShawn McCarney     env.incrementRuleDepth("set_voltage_rule");
1152134ca66SShawn McCarney     env.incrementRuleDepth("set_voltage_rule");
116c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 2);
117c69a2750SShawn McCarney     env.decrementRuleDepth();
118c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 1);
119c69a2750SShawn McCarney     env.decrementRuleDepth();
120c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
121c69a2750SShawn McCarney     env.decrementRuleDepth();
122c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
123c69a2750SShawn McCarney }
124c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,GetAdditionalErrorData)125*421128efSShawn McCarney TEST(ActionEnvironmentTests, GetAdditionalErrorData)
126*421128efSShawn McCarney {
127*421128efSShawn McCarney     IDMap idMap{};
128*421128efSShawn McCarney     MockServices services{};
129*421128efSShawn McCarney     ActionEnvironment env{idMap, "", services};
130*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().size(), 0);
131*421128efSShawn McCarney 
132*421128efSShawn McCarney     env.addAdditionalErrorData("foo", "foo_value");
133*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().size(), 1);
134*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().at("foo"), "foo_value");
135*421128efSShawn McCarney 
136*421128efSShawn McCarney     env.addAdditionalErrorData("bar", "bar_value");
137*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().size(), 2);
138*421128efSShawn McCarney     EXPECT_EQ(env.getAdditionalErrorData().at("bar"), "bar_value");
139*421128efSShawn McCarney }
140*421128efSShawn McCarney 
TEST(ActionEnvironmentTests,GetDevice)141c69a2750SShawn McCarney TEST(ActionEnvironmentTests, GetDevice)
142c69a2750SShawn McCarney {
143c69a2750SShawn McCarney     // Create IDMap
144c69a2750SShawn McCarney     IDMap idMap{};
145afb7fc3fSShawn McCarney 
14673eaceebSBob King     // Create mock services.
14773eaceebSBob King     MockServices services{};
14873eaceebSBob King 
149afb7fc3fSShawn McCarney     // Create Device and add to IDMap
150afb7fc3fSShawn McCarney     std::unique_ptr<i2c::I2CInterface> i2cInterface =
151afb7fc3fSShawn McCarney         i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
152a76898f1SBob King     Device reg1{
153a76898f1SBob King         "regulator1", true,
154a76898f1SBob King         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
155afb7fc3fSShawn McCarney         std::move(i2cInterface)};
156c69a2750SShawn McCarney     idMap.addDevice(reg1);
157c69a2750SShawn McCarney 
15873eaceebSBob King     ActionEnvironment env{idMap, "regulator1", services};
159c69a2750SShawn McCarney 
160c69a2750SShawn McCarney     // Test where current device ID is in the IDMap
161c69a2750SShawn McCarney     try
162c69a2750SShawn McCarney     {
163c69a2750SShawn McCarney         Device& device = env.getDevice();
164c69a2750SShawn McCarney         EXPECT_EQ(device.getID(), "regulator1");
165c69a2750SShawn McCarney         EXPECT_EQ(&device, &reg1);
166c69a2750SShawn McCarney     }
167c69a2750SShawn McCarney     catch (const std::exception& error)
168c69a2750SShawn McCarney     {
169c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
170c69a2750SShawn McCarney     }
171c69a2750SShawn McCarney 
172c69a2750SShawn McCarney     // Test where current device ID is not in the IDMap
173c69a2750SShawn McCarney     env.setDeviceID("regulator2");
174c69a2750SShawn McCarney     try
175c69a2750SShawn McCarney     {
176c69a2750SShawn McCarney         env.getDevice();
177c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
178c69a2750SShawn McCarney     }
179c69a2750SShawn McCarney     catch (const std::invalid_argument& ia_error)
180c69a2750SShawn McCarney     {
181c69a2750SShawn McCarney         EXPECT_STREQ(ia_error.what(),
182c69a2750SShawn McCarney                      "Unable to find device with ID \"regulator2\"");
183c69a2750SShawn McCarney     }
184c69a2750SShawn McCarney     catch (const std::exception& error)
185c69a2750SShawn McCarney     {
186c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
187c69a2750SShawn McCarney     }
188c69a2750SShawn McCarney }
189c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,GetDeviceID)190c69a2750SShawn McCarney TEST(ActionEnvironmentTests, GetDeviceID)
191c69a2750SShawn McCarney {
192c69a2750SShawn McCarney     IDMap idMap{};
19373eaceebSBob King     MockServices services{};
19473eaceebSBob King     ActionEnvironment env{idMap, "", services};
195c69a2750SShawn McCarney     EXPECT_EQ(env.getDeviceID(), "");
196c69a2750SShawn McCarney     env.setDeviceID("regulator1");
197c69a2750SShawn McCarney     EXPECT_EQ(env.getDeviceID(), "regulator1");
198c69a2750SShawn McCarney }
199c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,GetPhaseFaults)200*421128efSShawn McCarney TEST(ActionEnvironmentTests, GetPhaseFaults)
201*421128efSShawn McCarney {
202*421128efSShawn McCarney     IDMap idMap{};
203*421128efSShawn McCarney     MockServices services{};
204*421128efSShawn McCarney     ActionEnvironment env{idMap, "", services};
205*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 0);
206*421128efSShawn McCarney 
207*421128efSShawn McCarney     env.addPhaseFault(PhaseFaultType::n);
208*421128efSShawn McCarney     env.addPhaseFault(PhaseFaultType::n_plus_1);
209*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().size(), 2);
210*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n), 1);
211*421128efSShawn McCarney     EXPECT_EQ(env.getPhaseFaults().count(PhaseFaultType::n_plus_1), 1);
212*421128efSShawn McCarney }
213*421128efSShawn McCarney 
TEST(ActionEnvironmentTests,GetRule)214c69a2750SShawn McCarney TEST(ActionEnvironmentTests, GetRule)
215c69a2750SShawn McCarney {
216c69a2750SShawn McCarney     // Create IDMap
217c69a2750SShawn McCarney     IDMap idMap{};
21873eaceebSBob King 
21973eaceebSBob King     // Create mock services.
22073eaceebSBob King     MockServices services{};
22173eaceebSBob King 
2229fc08e73SShawn McCarney     Rule setVoltageRule{"set_voltage_rule",
2239fc08e73SShawn McCarney                         std::vector<std::unique_ptr<Action>>{}};
224c69a2750SShawn McCarney     idMap.addRule(setVoltageRule);
225c69a2750SShawn McCarney 
22673eaceebSBob King     ActionEnvironment env{idMap, "", services};
227c69a2750SShawn McCarney 
228c69a2750SShawn McCarney     // Test where rule ID is in the IDMap
229c69a2750SShawn McCarney     try
230c69a2750SShawn McCarney     {
231c69a2750SShawn McCarney         Rule& rule = env.getRule("set_voltage_rule");
232c69a2750SShawn McCarney         EXPECT_EQ(rule.getID(), "set_voltage_rule");
233c69a2750SShawn McCarney         EXPECT_EQ(&rule, &setVoltageRule);
234c69a2750SShawn McCarney     }
235c69a2750SShawn McCarney     catch (const std::exception& error)
236c69a2750SShawn McCarney     {
237c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
238c69a2750SShawn McCarney     }
239c69a2750SShawn McCarney 
240c69a2750SShawn McCarney     // Test where rule ID is not in the IDMap
241c69a2750SShawn McCarney     try
242c69a2750SShawn McCarney     {
243c69a2750SShawn McCarney         env.getRule("set_voltage_rule2");
244c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have reached this line.";
245c69a2750SShawn McCarney     }
246c69a2750SShawn McCarney     catch (const std::invalid_argument& ia_error)
247c69a2750SShawn McCarney     {
248c69a2750SShawn McCarney         EXPECT_STREQ(ia_error.what(),
249c69a2750SShawn McCarney                      "Unable to find rule with ID \"set_voltage_rule2\"");
250c69a2750SShawn McCarney     }
251c69a2750SShawn McCarney     catch (const std::exception& error)
252c69a2750SShawn McCarney     {
253c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
254c69a2750SShawn McCarney     }
255c69a2750SShawn McCarney }
256c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,GetRuleDepth)257c69a2750SShawn McCarney TEST(ActionEnvironmentTests, GetRuleDepth)
258c69a2750SShawn McCarney {
259c69a2750SShawn McCarney     IDMap idMap{};
26073eaceebSBob King     MockServices services{};
26173eaceebSBob King     ActionEnvironment env{idMap, "", services};
262c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
2632134ca66SShawn McCarney     env.incrementRuleDepth("set_voltage_rule");
264c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 1);
2652134ca66SShawn McCarney     env.incrementRuleDepth("set_voltage_rule");
266c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 2);
267c69a2750SShawn McCarney     env.decrementRuleDepth();
268c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 1);
269c69a2750SShawn McCarney     env.decrementRuleDepth();
270c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
271c69a2750SShawn McCarney }
272c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,GetServices)27373eaceebSBob King TEST(ActionEnvironmentTests, GetServices)
27473eaceebSBob King {
27573eaceebSBob King     IDMap idMap{};
27673eaceebSBob King     MockServices services{};
27773eaceebSBob King     ActionEnvironment env{idMap, "", services};
27873eaceebSBob King     EXPECT_EQ(&(env.getServices()), &services);
27973eaceebSBob King }
28073eaceebSBob King 
TEST(ActionEnvironmentTests,GetVolts)281c69a2750SShawn McCarney TEST(ActionEnvironmentTests, GetVolts)
282c69a2750SShawn McCarney {
283c69a2750SShawn McCarney     IDMap idMap{};
28473eaceebSBob King     MockServices services{};
28573eaceebSBob King     ActionEnvironment env{idMap, "", services};
2860fd07d7dSShawn McCarney     EXPECT_EQ(env.getVolts().has_value(), false);
287c69a2750SShawn McCarney     env.setVolts(1.31);
2880fd07d7dSShawn McCarney     EXPECT_EQ(env.getVolts().has_value(), true);
2890fd07d7dSShawn McCarney     EXPECT_EQ(env.getVolts().value(), 1.31);
290c69a2750SShawn McCarney }
291c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,IncrementRuleDepth)292c69a2750SShawn McCarney TEST(ActionEnvironmentTests, IncrementRuleDepth)
293c69a2750SShawn McCarney {
294c69a2750SShawn McCarney     IDMap idMap{};
29573eaceebSBob King     MockServices services{};
29673eaceebSBob King     ActionEnvironment env{idMap, "", services};
297c69a2750SShawn McCarney     EXPECT_EQ(env.getRuleDepth(), 0);
298c69a2750SShawn McCarney 
299c69a2750SShawn McCarney     // Test where rule depth has not exceeded maximum
300c69a2750SShawn McCarney     try
301c69a2750SShawn McCarney     {
302c69a2750SShawn McCarney         for (size_t i = 1; i <= env.maxRuleDepth; ++i)
303c69a2750SShawn McCarney         {
3042134ca66SShawn McCarney             env.incrementRuleDepth("set_voltage_rule");
305c69a2750SShawn McCarney             EXPECT_EQ(env.getRuleDepth(), i);
306c69a2750SShawn McCarney         }
307c69a2750SShawn McCarney     }
308c69a2750SShawn McCarney     catch (const std::exception& error)
309c69a2750SShawn McCarney     {
310c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
311c69a2750SShawn McCarney     }
312c69a2750SShawn McCarney 
313c69a2750SShawn McCarney     // Test where rule depth has exceeded maximum
314c69a2750SShawn McCarney     try
315c69a2750SShawn McCarney     {
3162134ca66SShawn McCarney         env.incrementRuleDepth("set_voltage_rule");
317c69a2750SShawn McCarney     }
318c69a2750SShawn McCarney     catch (const std::runtime_error& r_error)
319c69a2750SShawn McCarney     {
3202134ca66SShawn McCarney         EXPECT_STREQ(r_error.what(),
3212134ca66SShawn McCarney                      "Maximum rule depth exceeded by rule set_voltage_rule.");
322c69a2750SShawn McCarney     }
323c69a2750SShawn McCarney     catch (const std::exception& error)
324c69a2750SShawn McCarney     {
325c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
326c69a2750SShawn McCarney     }
327c69a2750SShawn McCarney }
328c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,SetDeviceID)329c69a2750SShawn McCarney TEST(ActionEnvironmentTests, SetDeviceID)
330c69a2750SShawn McCarney {
331c69a2750SShawn McCarney     IDMap idMap{};
33273eaceebSBob King     MockServices services{};
33373eaceebSBob King     ActionEnvironment env{idMap, "regulator1", services};
334c69a2750SShawn McCarney     EXPECT_EQ(env.getDeviceID(), "regulator1");
335c69a2750SShawn McCarney     env.setDeviceID("regulator2");
336c69a2750SShawn McCarney     EXPECT_EQ(env.getDeviceID(), "regulator2");
337c69a2750SShawn McCarney }
338c69a2750SShawn McCarney 
TEST(ActionEnvironmentTests,SetVolts)339c69a2750SShawn McCarney TEST(ActionEnvironmentTests, SetVolts)
340c69a2750SShawn McCarney {
341c69a2750SShawn McCarney     try
342c69a2750SShawn McCarney     {
343c69a2750SShawn McCarney         IDMap idMap{};
34473eaceebSBob King         MockServices services{};
34573eaceebSBob King         ActionEnvironment env{idMap, "", services};
3460fd07d7dSShawn McCarney         EXPECT_EQ(env.getVolts().has_value(), false);
347c69a2750SShawn McCarney         env.setVolts(2.35);
3480fd07d7dSShawn McCarney         EXPECT_EQ(env.getVolts().has_value(), true);
3490fd07d7dSShawn McCarney         EXPECT_EQ(env.getVolts().value(), 2.35);
350c69a2750SShawn McCarney     }
351c69a2750SShawn McCarney     catch (const std::exception& error)
352c69a2750SShawn McCarney     {
353c69a2750SShawn McCarney         ADD_FAILURE() << "Should not have caught exception.";
354c69a2750SShawn McCarney     }
355c69a2750SShawn McCarney }
356