blob: d3d0ab0889f9a6c732efb7b09f88a7fc47e5a2f2 [file] [log] [blame]
Shawn McCarney8215be32020-02-19 10:00:57 -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_bit_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(I2CCompareBitActionTests, Constructor)
41{
42 // Test where works
43 try
44 {
45 I2CCompareBitAction action{0x7C, 2, 0};
46 EXPECT_EQ(action.getRegister(), 0x7C);
47 EXPECT_EQ(action.getPosition(), 2);
48 EXPECT_EQ(action.getValue(), 0);
49 }
50 catch (...)
51 {
52 ADD_FAILURE() << "Should not have caught exception.";
53 }
54
55 // Test where fails: Invalid bit position > 7
56 try
57 {
58 I2CCompareBitAction action{0x7C, 8, 0};
59 ADD_FAILURE() << "Should not have reached this line.";
60 }
61 catch (const std::invalid_argument& e)
62 {
63 EXPECT_STREQ(e.what(), "Invalid bit position: 8");
64 }
65 catch (...)
66 {
67 ADD_FAILURE() << "Should not have caught exception.";
68 }
69
70 // Test where fails: Invalid bit value > 1
71 try
72 {
73 I2CCompareBitAction action{0x7C, 2, 2};
74 ADD_FAILURE() << "Should not have reached this line.";
75 }
76 catch (const std::invalid_argument& e)
77 {
78 EXPECT_STREQ(e.what(), "Invalid bit value: 2");
79 }
80 catch (...)
81 {
82 ADD_FAILURE() << "Should not have caught exception.";
83 }
84}
85
86TEST(I2CCompareBitActionTests, Execute)
87{
88 // Test where works
89 try
90 {
91 // Create mock I2CInterface: read() returns value 0x96 (1001 0110)
92 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
93 std::make_unique<i2c::MockedI2CInterface>();
94 EXPECT_CALL(*i2cInterface, isOpen).WillRepeatedly(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -060095 EXPECT_CALL(*i2cInterface, read(0x7C, A<uint8_t&>()))
Shawn McCarney8215be32020-02-19 10:00:57 -060096 .WillRepeatedly(SetArgReferee<1>(0x96));
97
98 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +080099 Device device{
100 "reg1", true,
101 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
102 std::move(i2cInterface)};
Shawn McCarney8215be32020-02-19 10:00:57 -0600103 IDMap idMap{};
104 idMap.addDevice(device);
105 ActionEnvironment env{idMap, "reg1"};
106
107 // Test where actual bit value is equal to expected bit value.
108 // Test all bits in register value 0x96 == 1001 0110).
109 {
110 I2CCompareBitAction actions[] = {I2CCompareBitAction{0x7C, 7, 1},
111 I2CCompareBitAction{0x7C, 6, 0},
112 I2CCompareBitAction{0x7C, 5, 0},
113 I2CCompareBitAction{0x7C, 4, 1},
114 I2CCompareBitAction{0x7C, 3, 0},
115 I2CCompareBitAction{0x7C, 2, 1},
116 I2CCompareBitAction{0x7C, 1, 1},
117 I2CCompareBitAction{0x7C, 0, 0}};
118 for (I2CCompareBitAction& action : actions)
119 {
120 EXPECT_EQ(action.execute(env), true);
121 }
122 }
123
124 // Test where actual bit value is not equal to expected bit value.
125 // Test all bits in register value 0x96 == 1001 0110).
126 {
127 I2CCompareBitAction actions[] = {I2CCompareBitAction{0x7C, 7, 0},
128 I2CCompareBitAction{0x7C, 6, 1},
129 I2CCompareBitAction{0x7C, 5, 1},
130 I2CCompareBitAction{0x7C, 4, 0},
131 I2CCompareBitAction{0x7C, 3, 1},
132 I2CCompareBitAction{0x7C, 2, 0},
133 I2CCompareBitAction{0x7C, 1, 0},
134 I2CCompareBitAction{0x7C, 0, 1}};
135 for (I2CCompareBitAction& action : actions)
136 {
137 EXPECT_EQ(action.execute(env), false);
138 }
139 }
140 }
141 catch (...)
142 {
143 ADD_FAILURE() << "Should not have caught exception.";
144 }
145
146 // Test where fails: Getting I2CInterface fails
147 try
148 {
149 // Create IDMap and ActionEnvironment
150 IDMap idMap{};
151 ActionEnvironment env{idMap, "reg1"};
152
153 I2CCompareBitAction action{0x7C, 5, 1};
154 action.execute(env);
155 ADD_FAILURE() << "Should not have reached this line.";
156 }
157 catch (const std::invalid_argument& e)
158 {
159 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
160 }
161 catch (...)
162 {
163 ADD_FAILURE() << "Should not have caught exception.";
164 }
165
166 // Test where fails: Reading byte fails
167 try
168 {
169 // Create mock I2CInterface: read() throws an I2CException
170 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
171 std::make_unique<i2c::MockedI2CInterface>();
172 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600173 EXPECT_CALL(*i2cInterface, read(0x7C, A<uint8_t&>()))
Shawn McCarney8215be32020-02-19 10:00:57 -0600174 .Times(1)
175 .WillOnce(Throw(
176 i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
177
178 // Create Device, IDMap, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800179 Device device{
180 "reg1", true,
181 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
182 std::move(i2cInterface)};
Shawn McCarney8215be32020-02-19 10:00:57 -0600183 IDMap idMap{};
184 idMap.addDevice(device);
185 ActionEnvironment env{idMap, "reg1"};
186
187 I2CCompareBitAction action{0x7C, 5, 1};
188 action.execute(env);
189 ADD_FAILURE() << "Should not have reached this line.";
190 }
191 catch (const ActionError& e)
192 {
193 EXPECT_STREQ(e.what(), "ActionError: i2c_compare_bit: { register: "
194 "0x7C, position: 5, value: 1 }");
195 try
196 {
197 // Re-throw inner I2CException
198 std::rethrow_if_nested(e);
199 ADD_FAILURE() << "Should not have reached this line.";
200 }
201 catch (const i2c::I2CException& ie)
202 {
203 EXPECT_STREQ(
204 ie.what(),
205 "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70");
206 }
207 catch (...)
208 {
209 ADD_FAILURE() << "Should not have caught exception.";
210 }
211 }
212 catch (...)
213 {
214 ADD_FAILURE() << "Should not have caught exception.";
215 }
216}
217
218TEST(I2CCompareBitActionTests, GetRegister)
219{
220 I2CCompareBitAction action{0x7C, 5, 1};
221 EXPECT_EQ(action.getRegister(), 0x7C);
222}
223
224TEST(I2CCompareBitActionTests, GetPosition)
225{
226 I2CCompareBitAction action{0x7C, 5, 1};
227 EXPECT_EQ(action.getPosition(), 5);
228}
229
230TEST(I2CCompareBitActionTests, GetValue)
231{
232 I2CCompareBitAction action{0x7C, 5, 1};
233 EXPECT_EQ(action.getValue(), 1);
234}
235
236TEST(I2CCompareBitActionTests, ToString)
237{
238 I2CCompareBitAction action{0x7C, 5, 1};
239 EXPECT_EQ(action.toString(),
240 "i2c_compare_bit: { register: 0x7C, position: 5, value: 1 }");
241}