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