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 "rule.hpp"
23 
24 #include <cstddef> // for size_t
25 #include <exception>
26 #include <memory>
27 #include <stdexcept>
28 #include <utility>
29 #include <vector>
30 
31 #include <gtest/gtest.h>
32 
33 using namespace phosphor::power::regulators;
34 
35 TEST(ActionEnvironmentTests, Constructor)
36 {
37     // Create IDMap
38     IDMap idMap{};
39 
40     // Create mock services.
41     MockServices services{};
42 
43     // Create Device and add to IDMap
44     std::unique_ptr<i2c::I2CInterface> i2cInterface =
45         i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
46     Device reg1{
47         "regulator1", true,
48         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
49         std::move(i2cInterface)};
50     idMap.addDevice(reg1);
51 
52     // Verify object state after constructor
53     try
54     {
55         ActionEnvironment env{idMap, "regulator1", services};
56         EXPECT_EQ(env.getDevice().getID(), "regulator1");
57         EXPECT_EQ(env.getDeviceID(), "regulator1");
58         EXPECT_EQ(env.getRuleDepth(), 0);
59         EXPECT_EQ(env.getVolts().has_value(), false);
60     }
61     catch (const std::exception& error)
62     {
63         ADD_FAILURE() << "Should not have caught exception.";
64     }
65 }
66 
67 TEST(ActionEnvironmentTests, DecrementRuleDepth)
68 {
69     IDMap idMap{};
70     MockServices services{};
71     ActionEnvironment env{idMap, "", services};
72     EXPECT_EQ(env.getRuleDepth(), 0);
73     env.incrementRuleDepth("set_voltage_rule");
74     env.incrementRuleDepth("set_voltage_rule");
75     EXPECT_EQ(env.getRuleDepth(), 2);
76     env.decrementRuleDepth();
77     EXPECT_EQ(env.getRuleDepth(), 1);
78     env.decrementRuleDepth();
79     EXPECT_EQ(env.getRuleDepth(), 0);
80     env.decrementRuleDepth();
81     EXPECT_EQ(env.getRuleDepth(), 0);
82 }
83 
84 TEST(ActionEnvironmentTests, GetDevice)
85 {
86     // Create IDMap
87     IDMap idMap{};
88 
89     // Create mock services.
90     MockServices services{};
91 
92     // Create Device and add to IDMap
93     std::unique_ptr<i2c::I2CInterface> i2cInterface =
94         i2c::create(1, 0x70, i2c::I2CInterface::InitialState::CLOSED);
95     Device reg1{
96         "regulator1", true,
97         "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
98         std::move(i2cInterface)};
99     idMap.addDevice(reg1);
100 
101     ActionEnvironment env{idMap, "regulator1", services};
102 
103     // Test where current device ID is in the IDMap
104     try
105     {
106         Device& device = env.getDevice();
107         EXPECT_EQ(device.getID(), "regulator1");
108         EXPECT_EQ(&device, &reg1);
109     }
110     catch (const std::exception& error)
111     {
112         ADD_FAILURE() << "Should not have caught exception.";
113     }
114 
115     // Test where current device ID is not in the IDMap
116     env.setDeviceID("regulator2");
117     try
118     {
119         env.getDevice();
120         ADD_FAILURE() << "Should not have reached this line.";
121     }
122     catch (const std::invalid_argument& ia_error)
123     {
124         EXPECT_STREQ(ia_error.what(),
125                      "Unable to find device with ID \"regulator2\"");
126     }
127     catch (const std::exception& error)
128     {
129         ADD_FAILURE() << "Should not have caught exception.";
130     }
131 }
132 
133 TEST(ActionEnvironmentTests, GetDeviceID)
134 {
135     IDMap idMap{};
136     MockServices services{};
137     ActionEnvironment env{idMap, "", services};
138     EXPECT_EQ(env.getDeviceID(), "");
139     env.setDeviceID("regulator1");
140     EXPECT_EQ(env.getDeviceID(), "regulator1");
141 }
142 
143 TEST(ActionEnvironmentTests, GetRule)
144 {
145     // Create IDMap
146     IDMap idMap{};
147 
148     // Create mock services.
149     MockServices services{};
150 
151     Rule setVoltageRule{"set_voltage_rule",
152                         std::vector<std::unique_ptr<Action>>{}};
153     idMap.addRule(setVoltageRule);
154 
155     ActionEnvironment env{idMap, "", services};
156 
157     // Test where rule ID is in the IDMap
158     try
159     {
160         Rule& rule = env.getRule("set_voltage_rule");
161         EXPECT_EQ(rule.getID(), "set_voltage_rule");
162         EXPECT_EQ(&rule, &setVoltageRule);
163     }
164     catch (const std::exception& error)
165     {
166         ADD_FAILURE() << "Should not have caught exception.";
167     }
168 
169     // Test where rule ID is not in the IDMap
170     try
171     {
172         env.getRule("set_voltage_rule2");
173         ADD_FAILURE() << "Should not have reached this line.";
174     }
175     catch (const std::invalid_argument& ia_error)
176     {
177         EXPECT_STREQ(ia_error.what(),
178                      "Unable to find rule with ID \"set_voltage_rule2\"");
179     }
180     catch (const std::exception& error)
181     {
182         ADD_FAILURE() << "Should not have caught exception.";
183     }
184 }
185 
186 TEST(ActionEnvironmentTests, GetRuleDepth)
187 {
188     IDMap idMap{};
189     MockServices services{};
190     ActionEnvironment env{idMap, "", services};
191     EXPECT_EQ(env.getRuleDepth(), 0);
192     env.incrementRuleDepth("set_voltage_rule");
193     EXPECT_EQ(env.getRuleDepth(), 1);
194     env.incrementRuleDepth("set_voltage_rule");
195     EXPECT_EQ(env.getRuleDepth(), 2);
196     env.decrementRuleDepth();
197     EXPECT_EQ(env.getRuleDepth(), 1);
198     env.decrementRuleDepth();
199     EXPECT_EQ(env.getRuleDepth(), 0);
200 }
201 
202 TEST(ActionEnvironmentTests, GetServices)
203 {
204     IDMap idMap{};
205     MockServices services{};
206     ActionEnvironment env{idMap, "", services};
207     EXPECT_EQ(&(env.getServices()), &services);
208 }
209 
210 TEST(ActionEnvironmentTests, GetVolts)
211 {
212     IDMap idMap{};
213     MockServices services{};
214     ActionEnvironment env{idMap, "", services};
215     EXPECT_EQ(env.getVolts().has_value(), false);
216     env.setVolts(1.31);
217     EXPECT_EQ(env.getVolts().has_value(), true);
218     EXPECT_EQ(env.getVolts().value(), 1.31);
219 }
220 
221 TEST(ActionEnvironmentTests, IncrementRuleDepth)
222 {
223     IDMap idMap{};
224     MockServices services{};
225     ActionEnvironment env{idMap, "", services};
226     EXPECT_EQ(env.getRuleDepth(), 0);
227 
228     // Test where rule depth has not exceeded maximum
229     try
230     {
231         for (size_t i = 1; i <= env.maxRuleDepth; ++i)
232         {
233             env.incrementRuleDepth("set_voltage_rule");
234             EXPECT_EQ(env.getRuleDepth(), i);
235         }
236     }
237     catch (const std::exception& error)
238     {
239         ADD_FAILURE() << "Should not have caught exception.";
240     }
241 
242     // Test where rule depth has exceeded maximum
243     try
244     {
245         env.incrementRuleDepth("set_voltage_rule");
246     }
247     catch (const std::runtime_error& r_error)
248     {
249         EXPECT_STREQ(r_error.what(),
250                      "Maximum rule depth exceeded by rule set_voltage_rule.");
251     }
252     catch (const std::exception& error)
253     {
254         ADD_FAILURE() << "Should not have caught exception.";
255     }
256 }
257 
258 TEST(ActionEnvironmentTests, SetDeviceID)
259 {
260     IDMap idMap{};
261     MockServices services{};
262     ActionEnvironment env{idMap, "regulator1", services};
263     EXPECT_EQ(env.getDeviceID(), "regulator1");
264     env.setDeviceID("regulator2");
265     EXPECT_EQ(env.getDeviceID(), "regulator2");
266 }
267 
268 TEST(ActionEnvironmentTests, SetVolts)
269 {
270     try
271     {
272         IDMap idMap{};
273         MockServices services{};
274         ActionEnvironment env{idMap, "", services};
275         EXPECT_EQ(env.getVolts().has_value(), false);
276         env.setVolts(2.35);
277         EXPECT_EQ(env.getVolts().has_value(), true);
278         EXPECT_EQ(env.getVolts().value(), 2.35);
279     }
280     catch (const std::exception& error)
281     {
282         ADD_FAILURE() << "Should not have caught exception.";
283     }
284 }
285