blob: 1bd47483e10b2dc57f51a527ed00c2cf1c77c20c [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
Bob Kinga76898f2020-10-13 15:08:33 +080073 Device device{
74 "reg1", true,
75 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
76 std::move(i2cInterface)};
Shawn McCarneyb38da992020-02-13 08:55:46 -060077 IDMap idMap{};
78 idMap.addDevice(device);
79 ActionEnvironment env{idMap, "reg1"};
80
81 // Actual value: 0xD7 = 1101 0111
82 // Mask : 0x7E = 0111 1110
83 // Result : 0x56 = 0101 0110
84 I2CCompareByteAction action{0xA0, 0x56, 0x7E};
85 EXPECT_EQ(action.execute(env), true);
86 }
87 catch (...)
88 {
89 ADD_FAILURE() << "Should not have caught exception.";
90 }
91
92 // Test where works: Equal: Mask not specified
93 try
94 {
95 // Create mock I2CInterface: read() returns value 0xD7
96 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
97 std::make_unique<i2c::MockedI2CInterface>();
98 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -060099 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600100 .Times(1)
101 .WillOnce(SetArgReferee<1>(0xD7));
102
103 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800104 Device device{
105 "reg1", true,
106 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
107 std::move(i2cInterface)};
Shawn McCarneyb38da992020-02-13 08:55:46 -0600108 IDMap idMap{};
109 idMap.addDevice(device);
110 ActionEnvironment env{idMap, "reg1"};
111
112 I2CCompareByteAction action{0xA0, 0xD7};
113 EXPECT_EQ(action.execute(env), true);
114 }
115 catch (...)
116 {
117 ADD_FAILURE() << "Should not have caught exception.";
118 }
119
120 // Test where works: Not equal: Mask specified
121 try
122 {
123 // Create mock I2CInterface: read() returns value 0xD7
124 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
125 std::make_unique<i2c::MockedI2CInterface>();
126 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600127 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600128 .Times(1)
129 .WillOnce(SetArgReferee<1>(0xD7));
130
131 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800132 Device device{
133 "reg1", true,
134 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
135 std::move(i2cInterface)};
Shawn McCarneyb38da992020-02-13 08:55:46 -0600136 IDMap idMap{};
137 idMap.addDevice(device);
138 ActionEnvironment env{idMap, "reg1"};
139
140 // Actual value: 0xD7 = 1101 0111
141 // Mask : 0x7E = 0111 1110
142 // Result : 0x56 = 0101 0110
143 I2CCompareByteAction action{0xA0, 0x57, 0x7E};
144 EXPECT_EQ(action.execute(env), false);
145 }
146 catch (...)
147 {
148 ADD_FAILURE() << "Should not have caught exception.";
149 }
150
151 // Test where works: Not equal: Mask not specified
152 try
153 {
154 // Create mock I2CInterface: read() returns value 0xD7
155 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
156 std::make_unique<i2c::MockedI2CInterface>();
157 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600158 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600159 .Times(1)
160 .WillOnce(SetArgReferee<1>(0xD7));
161
162 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800163 Device device{
164 "reg1", true,
165 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
166 std::move(i2cInterface)};
Shawn McCarneyb38da992020-02-13 08:55:46 -0600167 IDMap idMap{};
168 idMap.addDevice(device);
169 ActionEnvironment env{idMap, "reg1"};
170
171 I2CCompareByteAction action{0xA0, 0xD6};
172 EXPECT_EQ(action.execute(env), false);
173 }
174 catch (...)
175 {
176 ADD_FAILURE() << "Should not have caught exception.";
177 }
178
179 // Test where fails: Getting I2CInterface fails
180 try
181 {
182 // Create IDMap and ActionEnvironment
183 IDMap idMap{};
184 ActionEnvironment env{idMap, "reg1"};
185
186 I2CCompareByteAction action{0xA0, 0xD6};
187 action.execute(env);
188 ADD_FAILURE() << "Should not have reached this line.";
189 }
190 catch (const std::invalid_argument& e)
191 {
192 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
193 }
194 catch (...)
195 {
196 ADD_FAILURE() << "Should not have caught exception.";
197 }
198
199 // Test where fails: Reading byte fails
200 try
201 {
202 // Create mock I2CInterface: read() throws an I2CException
203 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
204 std::make_unique<i2c::MockedI2CInterface>();
205 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600206 EXPECT_CALL(*i2cInterface, read(0xA0, A<uint8_t&>()))
Shawn McCarneyb38da992020-02-13 08:55:46 -0600207 .Times(1)
208 .WillOnce(Throw(
209 i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
210
211 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800212 Device device{
213 "reg1", true,
214 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
215 std::move(i2cInterface)};
Shawn McCarneyb38da992020-02-13 08:55:46 -0600216 IDMap idMap{};
217 idMap.addDevice(device);
218 ActionEnvironment env{idMap, "reg1"};
219
220 I2CCompareByteAction action{0xA0, 0xD6};
221 action.execute(env);
222 ADD_FAILURE() << "Should not have reached this line.";
223 }
224 catch (const ActionError& e)
225 {
226 EXPECT_STREQ(e.what(), "ActionError: i2c_compare_byte: { register: "
227 "0xA0, value: 0xD6, mask: 0xFF }");
228 try
229 {
230 // Re-throw inner I2CException
231 std::rethrow_if_nested(e);
232 ADD_FAILURE() << "Should not have reached this line.";
233 }
234 catch (const i2c::I2CException& ie)
235 {
236 EXPECT_STREQ(
237 ie.what(),
238 "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70");
239 }
240 catch (...)
241 {
242 ADD_FAILURE() << "Should not have caught exception.";
243 }
244 }
245 catch (...)
246 {
247 ADD_FAILURE() << "Should not have caught exception.";
248 }
249}
250
251TEST(I2CCompareByteActionTests, GetRegister)
252{
253 I2CCompareByteAction action{0x7C, 0xDE};
254 EXPECT_EQ(action.getRegister(), 0x7C);
255}
256
257TEST(I2CCompareByteActionTests, GetValue)
258{
259 I2CCompareByteAction action{0xA0, 0x03, 0x47};
260 EXPECT_EQ(action.getValue(), 0x03);
261}
262
263TEST(I2CCompareByteActionTests, GetMask)
264{
265 // Test where mask is not specified
266 {
267 I2CCompareByteAction action{0x7C, 0xDE};
268 EXPECT_EQ(action.getMask(), 0xFF);
269 }
270
271 // Test where mask is specified
272 {
273 I2CCompareByteAction action{0xA0, 0x03, 0x47};
274 EXPECT_EQ(action.getMask(), 0x47);
275 }
276}
277
278TEST(I2CCompareByteActionTests, ToString)
279{
280 I2CCompareByteAction action{0x7C, 0xDE, 0xFE};
281 EXPECT_EQ(action.toString(),
282 "i2c_compare_byte: { register: 0x7C, value: 0xDE, mask: 0xFE }");
283}