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 "and_action.hpp"
19 #include "id_map.hpp"
20 #include "mock_action.hpp"
21 #include "mock_services.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
TEST(AndActionTests,Constructor)37 TEST(AndActionTests, Constructor)
38 {
39 std::vector<std::unique_ptr<Action>> actions{};
40 actions.push_back(std::make_unique<MockAction>());
41 actions.push_back(std::make_unique<MockAction>());
42
43 AndAction andAction{std::move(actions)};
44 EXPECT_EQ(andAction.getActions().size(), 2);
45 }
46
TEST(AndActionTests,Execute)47 TEST(AndActionTests, Execute)
48 {
49 // Create ActionEnvironment
50 IDMap idMap{};
51 MockServices services{};
52 ActionEnvironment env{idMap, "", services};
53
54 // Test where empty vector of actions is specified
55 try
56 {
57 std::vector<std::unique_ptr<Action>> actions{};
58 AndAction andAction{std::move(actions)};
59 EXPECT_EQ(andAction.execute(env), true);
60 }
61 catch (const std::exception& error)
62 {
63 ADD_FAILURE() << "Should not have caught exception.";
64 }
65
66 // Test where action throws an exception
67 try
68 {
69 std::vector<std::unique_ptr<Action>> actions{};
70 std::unique_ptr<MockAction> action;
71
72 // First action will throw an exception
73 action = std::make_unique<MockAction>();
74 EXPECT_CALL(*action, execute)
75 .Times(1)
76 .WillOnce(Throw(std::logic_error{"Communication error"}));
77 actions.push_back(std::move(action));
78
79 // Second action should not get executed
80 action = std::make_unique<MockAction>();
81 EXPECT_CALL(*action, execute).Times(0);
82 actions.push_back(std::move(action));
83
84 AndAction andAction{std::move(actions)};
85 andAction.execute(env);
86 ADD_FAILURE() << "Should not have reached this line.";
87 }
88 catch (const std::exception& error)
89 {
90 EXPECT_STREQ(error.what(), "Communication error");
91 }
92
93 // Test where middle action returns false
94 try
95 {
96 std::vector<std::unique_ptr<Action>> actions{};
97 std::unique_ptr<MockAction> action;
98
99 // First action will return true
100 action = std::make_unique<MockAction>();
101 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
102 actions.push_back(std::move(action));
103
104 // Second action will return false
105 action = std::make_unique<MockAction>();
106 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(false));
107 actions.push_back(std::move(action));
108
109 // Third action will return true
110 action = std::make_unique<MockAction>();
111 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
112 actions.push_back(std::move(action));
113
114 AndAction andAction{std::move(actions)};
115 EXPECT_EQ(andAction.execute(env), false);
116 }
117 catch (const std::exception& error)
118 {
119 ADD_FAILURE() << "Should not have caught exception.";
120 }
121
122 // Test where all actions return true
123 try
124 {
125 std::vector<std::unique_ptr<Action>> actions{};
126 std::unique_ptr<MockAction> action;
127
128 // First action will return true
129 action = std::make_unique<MockAction>();
130 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
131 actions.push_back(std::move(action));
132
133 // Second action will return true
134 action = std::make_unique<MockAction>();
135 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
136 actions.push_back(std::move(action));
137
138 // Third action will return true
139 action = std::make_unique<MockAction>();
140 EXPECT_CALL(*action, execute).Times(1).WillOnce(Return(true));
141 actions.push_back(std::move(action));
142
143 AndAction andAction{std::move(actions)};
144 EXPECT_EQ(andAction.execute(env), true);
145 }
146 catch (const std::exception& error)
147 {
148 ADD_FAILURE() << "Should not have caught exception.";
149 }
150 }
151
TEST(AndActionTests,GetActions)152 TEST(AndActionTests, GetActions)
153 {
154 std::vector<std::unique_ptr<Action>> actions{};
155
156 MockAction* action1 = new MockAction{};
157 actions.push_back(std::unique_ptr<MockAction>{action1});
158
159 MockAction* action2 = new MockAction{};
160 actions.push_back(std::unique_ptr<MockAction>{action2});
161
162 AndAction andAction{std::move(actions)};
163 EXPECT_EQ(andAction.getActions().size(), 2);
164 EXPECT_EQ(andAction.getActions()[0].get(), action1);
165 EXPECT_EQ(andAction.getActions()[1].get(), action2);
166 }
167
TEST(AndActionTests,ToString)168 TEST(AndActionTests, ToString)
169 {
170 std::vector<std::unique_ptr<Action>> actions{};
171 actions.push_back(std::make_unique<MockAction>());
172
173 AndAction andAction{std::move(actions)};
174 EXPECT_EQ(andAction.toString(), "and: [ ... ]");
175 }
176