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.hpp"
17 #include "action_environment.hpp"
18 #include "id_map.hpp"
19 #include "mock_action.hpp"
20 #include "mock_services.hpp"
21 #include "rule.hpp"
22 
23 #include <exception>
24 #include <memory>
25 #include <stdexcept>
26 #include <utility>
27 #include <vector>
28 
29 #include <gmock/gmock.h>
30 #include <gtest/gtest.h>
31 
32 using namespace phosphor::power::regulators;
33 
34 using ::testing::Return;
35 using ::testing::Throw;
36 
37 TEST(RuleTests, Constructor)
38 {
39     // Build vector of actions
40     std::vector<std::unique_ptr<Action>> actions{};
41     actions.push_back(std::make_unique<MockAction>());
42     actions.push_back(std::make_unique<MockAction>());
43 
44     // Create rule and verify data members
45     Rule rule("set_voltage_rule", std::move(actions));
46     EXPECT_EQ(rule.getID(), "set_voltage_rule");
47     EXPECT_EQ(rule.getActions().size(), 2);
48 }
49 
50 TEST(RuleTests, Execute)
51 {
52     // Create ActionEnvironment
53     IDMap idMap{};
54     MockServices services{};
55     ActionEnvironment env{idMap, "", services};
56 
57     // Test where an action throws an exception
58     try
59     {
60         std::vector<std::unique_ptr<Action>> actions{};
61         std::unique_ptr<MockAction> action = std::make_unique<MockAction>();
62         EXPECT_CALL(*action, execute)
63             .Times(1)
64             .WillOnce(Throw(std::logic_error{"Communication error"}));
65         actions.push_back(std::move(action));
66 
67         Rule rule("set_voltage_rule", std::move(actions));
68         rule.execute(env);
69         ADD_FAILURE() << "Should not have reached this line.";
70     }
71     catch (const std::exception& error)
72     {
73         EXPECT_STREQ(error.what(), "Communication error");
74     }
75 
76     // Test where all actions are executed
77     try
78     {
79         std::vector<std::unique_ptr<Action>> actions{};
80         std::unique_ptr<MockAction> action;
81 
82         // First action will return true
83         action = std::make_unique<MockAction>();
84         EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
85         actions.push_back(std::move(action));
86 
87         // Second action will return false
88         action = std::make_unique<MockAction>();
89         EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
90         actions.push_back(std::move(action));
91 
92         Rule rule("set_voltage_rule", std::move(actions));
93         EXPECT_EQ(rule.execute(env), false);
94     }
95     catch (const std::exception& error)
96     {
97         ADD_FAILURE() << "Should not have caught exception.";
98     }
99 }
100 
101 TEST(RuleTests, GetActions)
102 {
103     std::vector<std::unique_ptr<Action>> actions{};
104 
105     MockAction* action1 = new MockAction{};
106     actions.push_back(std::unique_ptr<MockAction>{action1});
107 
108     MockAction* action2 = new MockAction{};
109     actions.push_back(std::unique_ptr<MockAction>{action2});
110 
111     Rule rule("set_voltage_rule", std::move(actions));
112     EXPECT_EQ(rule.getActions().size(), 2);
113     EXPECT_EQ(rule.getActions()[0].get(), action1);
114     EXPECT_EQ(rule.getActions()[1].get(), action2);
115 }
116 
117 TEST(RuleTests, GetID)
118 {
119     Rule rule("read_sensor_values", std::vector<std::unique_ptr<Action>>{});
120     EXPECT_EQ(rule.getID(), "read_sensor_values");
121 }
122