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