blob: 609026e39d702ac71fd86e119b74bd39b5d0cc45 [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"
Bob King73eacee2020-10-23 13:58:02 +080022#include "mock_services.hpp"
Shawn McCarney8215be32020-02-19 10:00:57 -060023#include "mocked_i2c_interface.hpp"
24
25#include <cstdint>
26#include <memory>
27#include <stdexcept>
28#include <string>
29#include <utility>
30
31#include <gmock/gmock.h>
32#include <gtest/gtest.h>
33
34using namespace phosphor::power::regulators;
35
36using ::testing::A;
37using ::testing::Return;
38using ::testing::SetArgReferee;
39using ::testing::Throw;
40
41TEST(I2CCompareBitActionTests, Constructor)
42{
43 // Test where works
44 try
45 {
46 I2CCompareBitAction action{0x7C, 2, 0};
47 EXPECT_EQ(action.getRegister(), 0x7C);
48 EXPECT_EQ(action.getPosition(), 2);
49 EXPECT_EQ(action.getValue(), 0);
50 }
51 catch (...)
52 {
53 ADD_FAILURE() << "Should not have caught exception.";
54 }
55
56 // Test where fails: Invalid bit position > 7
57 try
58 {
59 I2CCompareBitAction action{0x7C, 8, 0};
60 ADD_FAILURE() << "Should not have reached this line.";
61 }
62 catch (const std::invalid_argument& e)
63 {
64 EXPECT_STREQ(e.what(), "Invalid bit position: 8");
65 }
66 catch (...)
67 {
68 ADD_FAILURE() << "Should not have caught exception.";
69 }
70
71 // Test where fails: Invalid bit value > 1
72 try
73 {
74 I2CCompareBitAction action{0x7C, 2, 2};
75 ADD_FAILURE() << "Should not have reached this line.";
76 }
77 catch (const std::invalid_argument& e)
78 {
79 EXPECT_STREQ(e.what(), "Invalid bit value: 2");
80 }
81 catch (...)
82 {
83 ADD_FAILURE() << "Should not have caught exception.";
84 }
85}
86
87TEST(I2CCompareBitActionTests, Execute)
88{
89 // Test where works
90 try
91 {
92 // Create mock I2CInterface: read() returns value 0x96 (1001 0110)
93 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
94 std::make_unique<i2c::MockedI2CInterface>();
95 EXPECT_CALL(*i2cInterface, isOpen).WillRepeatedly(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -060096 EXPECT_CALL(*i2cInterface, read(0x7C, A<uint8_t&>()))
Shawn McCarney8215be32020-02-19 10:00:57 -060097 .WillRepeatedly(SetArgReferee<1>(0x96));
98
Bob King73eacee2020-10-23 13:58:02 +080099 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800100 Device device{
101 "reg1", true,
102 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
103 std::move(i2cInterface)};
Shawn McCarney8215be32020-02-19 10:00:57 -0600104 IDMap idMap{};
105 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800106 MockServices services{};
107 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarney8215be32020-02-19 10:00:57 -0600108
109 // Test where actual bit value is equal to expected bit value.
110 // Test all bits in register value 0x96 == 1001 0110).
111 {
112 I2CCompareBitAction actions[] = {I2CCompareBitAction{0x7C, 7, 1},
113 I2CCompareBitAction{0x7C, 6, 0},
114 I2CCompareBitAction{0x7C, 5, 0},
115 I2CCompareBitAction{0x7C, 4, 1},
116 I2CCompareBitAction{0x7C, 3, 0},
117 I2CCompareBitAction{0x7C, 2, 1},
118 I2CCompareBitAction{0x7C, 1, 1},
119 I2CCompareBitAction{0x7C, 0, 0}};
120 for (I2CCompareBitAction& action : actions)
121 {
122 EXPECT_EQ(action.execute(env), true);
123 }
124 }
125
126 // Test where actual bit value is not equal to expected bit value.
127 // Test all bits in register value 0x96 == 1001 0110).
128 {
129 I2CCompareBitAction actions[] = {I2CCompareBitAction{0x7C, 7, 0},
130 I2CCompareBitAction{0x7C, 6, 1},
131 I2CCompareBitAction{0x7C, 5, 1},
132 I2CCompareBitAction{0x7C, 4, 0},
133 I2CCompareBitAction{0x7C, 3, 1},
134 I2CCompareBitAction{0x7C, 2, 0},
135 I2CCompareBitAction{0x7C, 1, 0},
136 I2CCompareBitAction{0x7C, 0, 1}};
137 for (I2CCompareBitAction& action : actions)
138 {
139 EXPECT_EQ(action.execute(env), false);
140 }
141 }
142 }
143 catch (...)
144 {
145 ADD_FAILURE() << "Should not have caught exception.";
146 }
147
148 // Test where fails: Getting I2CInterface fails
149 try
150 {
Bob King73eacee2020-10-23 13:58:02 +0800151 // Create IDMap, MockServices, and ActionEnvironment
Shawn McCarney8215be32020-02-19 10:00:57 -0600152 IDMap idMap{};
Bob King73eacee2020-10-23 13:58:02 +0800153 MockServices services{};
154 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarney8215be32020-02-19 10:00:57 -0600155
156 I2CCompareBitAction action{0x7C, 5, 1};
157 action.execute(env);
158 ADD_FAILURE() << "Should not have reached this line.";
159 }
160 catch (const std::invalid_argument& e)
161 {
162 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
163 }
164 catch (...)
165 {
166 ADD_FAILURE() << "Should not have caught exception.";
167 }
168
169 // Test where fails: Reading byte fails
170 try
171 {
172 // Create mock I2CInterface: read() throws an I2CException
173 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
174 std::make_unique<i2c::MockedI2CInterface>();
175 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
Shawn McCarney2c657002020-02-20 11:00:37 -0600176 EXPECT_CALL(*i2cInterface, read(0x7C, A<uint8_t&>()))
Shawn McCarney8215be32020-02-19 10:00:57 -0600177 .Times(1)
178 .WillOnce(Throw(
179 i2c::I2CException{"Failed to read byte", "/dev/i2c-1", 0x70}));
180
Bob King73eacee2020-10-23 13:58:02 +0800181 // Create Device, IDMap, MockServices, and ActionEnvironment
Bob Kinga76898f2020-10-13 15:08:33 +0800182 Device device{
183 "reg1", true,
184 "/xyz/openbmc_project/inventory/system/chassis/motherboard/reg1",
185 std::move(i2cInterface)};
Shawn McCarney8215be32020-02-19 10:00:57 -0600186 IDMap idMap{};
187 idMap.addDevice(device);
Bob King73eacee2020-10-23 13:58:02 +0800188 MockServices services{};
189 ActionEnvironment env{idMap, "reg1", services};
Shawn McCarney8215be32020-02-19 10:00:57 -0600190
191 I2CCompareBitAction action{0x7C, 5, 1};
192 action.execute(env);
193 ADD_FAILURE() << "Should not have reached this line.";
194 }
195 catch (const ActionError& e)
196 {
197 EXPECT_STREQ(e.what(), "ActionError: i2c_compare_bit: { register: "
198 "0x7C, position: 5, value: 1 }");
199 try
200 {
201 // Re-throw inner I2CException
202 std::rethrow_if_nested(e);
203 ADD_FAILURE() << "Should not have reached this line.";
204 }
205 catch (const i2c::I2CException& ie)
206 {
207 EXPECT_STREQ(
208 ie.what(),
209 "I2CException: Failed to read byte: bus /dev/i2c-1, addr 0x70");
210 }
211 catch (...)
212 {
213 ADD_FAILURE() << "Should not have caught exception.";
214 }
215 }
216 catch (...)
217 {
218 ADD_FAILURE() << "Should not have caught exception.";
219 }
220}
221
222TEST(I2CCompareBitActionTests, GetRegister)
223{
224 I2CCompareBitAction action{0x7C, 5, 1};
225 EXPECT_EQ(action.getRegister(), 0x7C);
226}
227
228TEST(I2CCompareBitActionTests, GetPosition)
229{
230 I2CCompareBitAction action{0x7C, 5, 1};
231 EXPECT_EQ(action.getPosition(), 5);
232}
233
234TEST(I2CCompareBitActionTests, GetValue)
235{
236 I2CCompareBitAction action{0x7C, 5, 1};
237 EXPECT_EQ(action.getValue(), 1);
238}
239
240TEST(I2CCompareBitActionTests, ToString)
241{
242 I2CCompareBitAction action{0x7C, 5, 1};
243 EXPECT_EQ(action.toString(),
244 "i2c_compare_bit: { register: 0x7C, position: 5, value: 1 }");
245}