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