blob: be94e5226de4bea16cbcc3b5b1d9e7dad3a6390f [file] [log] [blame]
Shawn McCarney2134ca62019-11-11 13:06:18 -06001/**
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.hpp"
17#include "action_environment.hpp"
18#include "device.hpp"
19#include "id_map.hpp"
20#include "mock_action.hpp"
21#include "rule.hpp"
22#include "run_rule_action.hpp"
23
24#include <exception>
25#include <memory>
26#include <stdexcept>
27#include <utility>
28#include <vector>
29
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32
33using namespace phosphor::power::regulators;
34
35using ::testing::Return;
36using ::testing::Throw;
37
38TEST(RunRuleActionTests, Constructor)
39{
40 RunRuleAction action{"set_voltage_rule"};
41 EXPECT_EQ(action.getRuleID(), "set_voltage_rule");
42}
43
44TEST(RunRuleActionTests, Execute)
45{
46 // Test where rule ID is not in the IDMap/ActionEnvironment
47 try
48 {
49 IDMap idMap{};
50 ActionEnvironment env{idMap, ""};
51 RunRuleAction runRuleAction{"set_voltage_rule"};
52 runRuleAction.execute(env);
53 ADD_FAILURE() << "Should not have reached this line.";
54 }
55 catch (const std::invalid_argument& ia_error)
56 {
57 EXPECT_STREQ(ia_error.what(),
58 "Unable to find rule with ID \"set_voltage_rule\"");
59 }
60 catch (const std::exception& error)
61 {
62 ADD_FAILURE() << "Should not have caught exception.";
63 }
64
65 // Test where a rule action throws an exception
66 try
67 {
68 // Create rule with action that throws an exception
69 std::vector<std::unique_ptr<Action>> actions{};
70 std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
71 EXPECT_CALL(*action, execute)
72 .Times(1)
73 .WillOnce(Throw(std::logic_error{"Communication error"}));
74 actions.push_back(std::move(action));
75 Rule rule("exception_rule", std::move(actions));
76
77 // Create ActionEnvironment
78 IDMap idMap{};
79 idMap.addRule(rule);
80 ActionEnvironment env{idMap, ""};
81
82 // Create RunRuleAction
83 RunRuleAction runRuleAction{"exception_rule"};
84 runRuleAction.execute(env);
85 ADD_FAILURE() << "Should not have reached this line.";
86 }
87 catch (const std::exception& error)
88 {
89 EXPECT_STREQ(error.what(), "Communication error");
90 }
91
92 // Test where rule calls itself and results in infinite recursion
93 try
94 {
95 // Create rule that calls itself
96 std::vector<std::unique_ptr<Action>> actions{};
97 actions.push_back(std::make_unique<RunRuleAction>("infinite_rule"));
98 Rule rule("infinite_rule", std::move(actions));
99
100 // Create ActionEnvironment
101 IDMap idMap{};
102 idMap.addRule(rule);
103 ActionEnvironment env{idMap, ""};
104
105 // Create RunRuleAction
106 RunRuleAction runRuleAction{"infinite_rule"};
107 runRuleAction.execute(env);
108 ADD_FAILURE() << "Should not have reached this line.";
109 }
110 catch (const std::runtime_error& r_error)
111 {
112 EXPECT_STREQ(r_error.what(),
113 "Maximum rule depth exceeded by rule infinite_rule.");
114 }
115 catch (const std::exception& error)
116 {
117 ADD_FAILURE() << "Should not have caught exception.";
118 }
119
120 // Test where last action returns false
121 try
122 {
123 // Create rule with two actions. Last action returns false.
124 std::vector<std::unique_ptr<Action>> actions{};
125 std::unique_ptr<MockAction> action;
126
127 action = std::make_unique<MockAction>();
128 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
129 actions.push_back(std::move(action));
130
131 action = std::make_unique<MockAction>();
132 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
133 actions.push_back(std::move(action));
134
135 Rule rule("set_voltage_rule", std::move(actions));
136
137 // Create ActionEnvironment
138 IDMap idMap{};
139 idMap.addRule(rule);
140 ActionEnvironment env{idMap, ""};
141
142 // Create RunRuleAction
143 RunRuleAction runRuleAction{"set_voltage_rule"};
144 EXPECT_EQ(runRuleAction.execute(env), false);
145 EXPECT_EQ(env.getRuleDepth(), 0);
146 }
147 catch (const std::exception& error)
148 {
149 ADD_FAILURE() << "Should not have caught exception.";
150 }
151
152 // Test where last action returns true
153 try
154 {
155 // Create rule with two actions. Last action returns true.
156 std::vector<std::unique_ptr<Action>> actions{};
157 std::unique_ptr<MockAction> action;
158
159 action = std::make_unique<MockAction>();
160 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
161 actions.push_back(std::move(action));
162
163 action = std::make_unique<MockAction>();
164 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
165 actions.push_back(std::move(action));
166
167 Rule rule("set_voltage_rule", std::move(actions));
168
169 // Create ActionEnvironment
170 IDMap idMap{};
171 idMap.addRule(rule);
172 ActionEnvironment env{idMap, ""};
173
174 // Create RunRuleAction
175 RunRuleAction runRuleAction{"set_voltage_rule"};
176 EXPECT_EQ(runRuleAction.execute(env), true);
177 EXPECT_EQ(env.getRuleDepth(), 0);
178 }
179 catch (const std::exception& error)
180 {
181 ADD_FAILURE() << "Should not have caught exception.";
182 }
183}
184
185TEST(RunRuleActionTests, GetRuleID)
186{
187 RunRuleAction action{"read_sensors_rule"};
188 EXPECT_EQ(action.getRuleID(), "read_sensors_rule");
189}