blob: 436d98755e2ac9d6eb0df13d4503a0c40e593a71 [file] [log] [blame]
Shawn McCarneyb38da992020-02-13 08:55:46 -06001/**
2 * Copyright © 2020 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_environment.hpp"
17#include "action_error.hpp"
18#include "device.hpp"
19#include "i2c_compare_byte_action.hpp"
20#include "i2c_interface.hpp"
21#include "id_map.hpp"
22#include "mocked_i2c_interface.hpp"
23
24#include <cstdint>
25#include <memory>
26#include <stdexcept>
27#include <string>
28#include <utility>
29
30#include <gmock/gmock.h>
31#include <gtest/gtest.h>
32
33using namespace phosphor::power::regulators;
34
35using ::testing::A;
36using ::testing::Return;
37using ::testing::SetArgReferee;
38using ::testing::Throw;
39
40TEST(I2CCompareByteActionTests, Constructor)
41{
42 // Test where mask is not specified
43 {
44 I2CCompareByteAction action{0x7C, 0xDE};
45 EXPECT_EQ(action.getRegister(), 0x7C);
46 EXPECT_EQ(action.getValue(), 0xDE);
47 EXPECT_EQ(action.getMask(), 0xFF);
48 }
49
50 // Test where mask is specified
51 {
52 I2CCompareByteAction action{0xA0, 0x03, 0x47};
53 EXPECT_EQ(action.getRegister(), 0xA0);
54 EXPECT_EQ(action.getValue(), 0x03);
55 EXPECT_EQ(action.getMask(), 0x47);
56 }
57}
58
59TEST(I2CCompareByteActionTests, Execute)
60{
61 // Test where works: Equal: Mask specified
62 try
63 {
64 // Create mock I2CInterface: read() returns value 0xD7
65 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
66 std::make_unique<i2c::MockedI2CInterface>();
67 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -060068 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -060069 .Times(1)
70 .WillOnce(SetArgReferee<1>(0xD7));
71
72 // Create Device, IDMap, and ActionEnvironment
73 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
74 std::move(i2cInterface)};
75 IDMap idMap{};
76 idMap.addDevice(device);
77 ActionEnvironment env{idMap, "reg1"};
78
79 // Actual value: 0xD7 = 1101 0111
80 // Mask : 0x7E = 0111 1110
81 // Result : 0x56 = 0101 0110
82 I2CCompareByteAction action{0xA0, 0x56, 0x7E};
83 EXPECT_EQ(action.execute(env), true);
84 }
85 catch (...)
86 {
87 ADD_FAILURE() << "Should not have caught exception.";
88 }
89
90 // Test where works: Equal: Mask not specified
91 try
92 {
93 // Create mock I2CInterface: read() returns value 0xD7
94 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
95 std::make_unique<i2c::MockedI2CInterface>();
96 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -060097 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -060098 .Times(1)
99 .WillOnce(SetArgReferee<1>(0xD7));
100
101 // Create Device, IDMap, and ActionEnvironment
102 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
103 std::move(i2cInterface)};
104 IDMap idMap{};
105 idMap.addDevice(device);
106 ActionEnvironment env{idMap, "reg1"};
107
108 I2CCompareByteAction action{0xA0, 0xD7};
109 EXPECT_EQ(action.execute(env), true);
110 }
111 catch (...)
112 {
113 ADD_FAILURE() << "Should not have caught exception.";
114 }
115
116 // Test where works: Not equal: Mask specified
117 try
118 {
119 // Create mock I2CInterface: read() returns value 0xD7
120 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
121 std::make_unique<i2c::MockedI2CInterface>();
122 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600123 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600124 .Times(1)
125 .WillOnce(SetArgReferee<1>(0xD7));
126
127 // Create Device, IDMap, and ActionEnvironment
128 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
129 std::move(i2cInterface)};
130 IDMap idMap{};
131 idMap.addDevice(device);
132 ActionEnvironment env{idMap, "reg1"};
133
134 // Actual value: 0xD7 = 1101 0111
135 // Mask : 0x7E = 0111 1110
136 // Result : 0x56 = 0101 0110
137 I2CCompareByteAction action{0xA0, 0x57, 0x7E};
138 EXPECT_EQ(action.execute(env), false);
139 }
140 catch (...)
141 {
142 ADD_FAILURE() << "Should not have caught exception.";
143 }
144
145 // Test where works: Not equal: Mask not specified
146 try
147 {
148 // Create mock I2CInterface: read() returns value 0xD7
149 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
150 std::make_unique<i2c::MockedI2CInterface>();
151 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600152 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600153 .Times(1)
154 .WillOnce(SetArgReferee<1>(0xD7));
155
156 // Create Device, IDMap, and ActionEnvironment
157 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
158 std::move(i2cInterface)};
159 IDMap idMap{};
160 idMap.addDevice(device);
161 ActionEnvironment env{idMap, "reg1"};
162
163 I2CCompareByteAction action{0xA0, 0xD6};
164 EXPECT_EQ(action.execute(env), false);
165 }
166 catch (...)
167 {
168 ADD_FAILURE() << "Should not have caught exception.";
169 }
170
171 // Test where fails: Getting I2CInterface fails
172 try
173 {
174 // Create IDMap and ActionEnvironment
175 IDMap idMap{};
176 ActionEnvironment env{idMap, "reg1"};
177
178 I2CCompareByteAction action{0xA0, 0xD6};
179 action.execute(env);
180 ADD_FAILURE() << "Should not have reached this line.";
181 }
182 catch (const std::invalid_argument& e)
183 {
184 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
185 }
186 catch (...)
187 {
188 ADD_FAILURE() << "Should not have caught exception.";
189 }
190
191 // Test where fails: Reading byte fails
192 try
193 {
194 // Create mock I2CInterface: read() throws an I2CException
195 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
196 std::make_unique<i2c::MockedI2CInterface>();
197 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600198 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600199 .Times(1)
200 .WillOnce(Throw(
201 i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
202
203 // Create Device, IDMap, and ActionEnvironment
204 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
205 std::move(i2cInterface)};
206 IDMap idMap{};
207 idMap.addDevice(device);
208 ActionEnvironment env{idMap, "reg1"};
209
210 I2CCompareByteAction action{0xA0, 0xD6};
211 action.execute(env);
212 ADD_FAILURE() << "Should not have reached this line.";
213 }
214 catch (const ActionError& e)
215 {
216 EXPECT_STREQ(e.what(), "ActionError: i2c_compare_byte: { register: "
217 "0xA0, value: 0xD6, mask: 0xFF }");
218 try
219 {
220 // Re-throw inner I2CException
221 std::rethrow_if_nested(e);
222 ADD_FAILURE() << "Should not have reached this line.";
223 }
224 catch (const i2c::I2CException& ie)
225 {
226 EXPECT_STREQ(
227 ie.what(),
228 "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70");
229 }
230 catch (...)
231 {
232 ADD_FAILURE() << "Should not have caught exception.";
233 }
234 }
235 catch (...)
236 {
237 ADD_FAILURE() << "Should not have caught exception.";
238 }
239}
240
241TEST(I2CCompareByteActionTests, GetRegister)
242{
243 I2CCompareByteAction action{0x7C, 0xDE};
244 EXPECT_EQ(action.getRegister(), 0x7C);
245}
246
247TEST(I2CCompareByteActionTests, GetValue)
248{
249 I2CCompareByteAction action{0xA0, 0x03, 0x47};
250 EXPECT_EQ(action.getValue(), 0x03);
251}
252
253TEST(I2CCompareByteActionTests, GetMask)
254{
255 // Test where mask is not specified
256 {
257 I2CCompareByteAction action{0x7C, 0xDE};
258 EXPECT_EQ(action.getMask(), 0xFF);
259 }
260
261 // Test where mask is specified
262 {
263 I2CCompareByteAction action{0xA0, 0x03, 0x47};
264 EXPECT_EQ(action.getMask(), 0x47);
265 }
266}
267
268TEST(I2CCompareByteActionTests, ToString)
269{
270 I2CCompareByteAction action{0x7C, 0xDE, 0xFE};
271 EXPECT_EQ(action.toString(),
272 "i2c_compare_byte: { register: 0x7C, value: 0xDE, mask: 0xFE }");
273}