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