blob: 70e55d77798f956b47d03b0989840bbc79500179 [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 "device.hpp"
18#include "i2c_action.hpp"
19#include "i2c_interface.hpp"
20#include "id_map.hpp"
21#include "mocked_i2c_interface.hpp"
22
23#include <memory>
24#include <stdexcept>
25#include <string>
26#include <utility>
27
28#include <gmock/gmock.h>
29#include <gtest/gtest.h>
30
31using namespace phosphor::power::regulators;
32
33using ::testing::Return;
34using ::testing::Throw;
35
36/**
37 * Define a test implementation of the I2CAction abstract base class.
38 */
39class I2CActionImpl : public I2CAction
40{
41 public:
42 virtual bool execute(ActionEnvironment& /* environment */) override
43 {
44 return true;
45 }
46
47 virtual std::string toString() const override
48 {
49 return "i2c_action_impl: {}";
50 }
51
52 // Make test a friend so it can access protected getI2CInterface() method
53 FRIEND_TEST(I2CActionTests, GetI2CInterface);
54};
55
56TEST(I2CActionTests, GetI2CInterface)
57{
58 // Test where works: device was not open
59 try
60 {
61 // Create mock I2CInterface
62 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
63 std::make_unique<i2c::MockedI2CInterface>();
64 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false));
65 EXPECT_CALL(*i2cInterface, open).Times(1);
66
67 // Create Device, IDMap, ActionEnvironment, and I2CAction
68 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
69 std::move(i2cInterface)};
70 IDMap idMap{};
71 idMap.addDevice(device);
72 ActionEnvironment env{idMap, "reg1"};
73 I2CActionImpl action{};
74
75 // Get I2CInterface. Should succeed without an exception.
76 action.getI2CInterface(env);
77 }
78 catch (...)
79 {
80 ADD_FAILURE() << "Should not have caught exception.";
81 }
82
83 // Test where works: device was already open
84 try
85 {
86 // Create mock I2CInterface
87 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
88 std::make_unique<i2c::MockedI2CInterface>();
89 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
90 EXPECT_CALL(*i2cInterface, open).Times(0);
91
92 // Create Device, IDMap, ActionEnvironment, and I2CAction
93 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
94 std::move(i2cInterface)};
95 IDMap idMap{};
96 idMap.addDevice(device);
97 ActionEnvironment env{idMap, "reg1"};
98 I2CActionImpl action{};
99
100 // Get I2CInterface. Should succeed without an exception.
101 action.getI2CInterface(env);
102 }
103 catch (...)
104 {
105 ADD_FAILURE() << "Should not have caught exception.";
106 }
107
108 // Test where fails: getting current device fails
109 try
110 {
111 // Create IDMap, ActionEnvironment, and I2CAction
112 IDMap idMap{};
113 ActionEnvironment env{idMap, "reg1"};
114 I2CActionImpl action{};
115
116 // Get I2CInterface. Should throw an exception since "reg1" is not a
117 // valid device in the IDMap.
118 action.getI2CInterface(env);
119 ADD_FAILURE() << "Should not have reached this line.";
120 }
121 catch (const std::invalid_argument& e)
122 {
123 EXPECT_STREQ(e.what(), "Unable to find device with ID \"reg1\"");
124 }
125 catch (...)
126 {
127 ADD_FAILURE() << "Should not have caught exception.";
128 }
129
130 // Test where fails: opening interface fails
131 try
132 {
133 // Create mock I2CInterface
134 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
135 std::make_unique<i2c::MockedI2CInterface>();
136 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(false));
137 EXPECT_CALL(*i2cInterface, open)
138 .Times(1)
139 .WillOnce(
140 Throw(i2c::I2CException{"Failed to open", "/dev/i2c-1", 0x70}));
141
142 // Create Device, IDMap, ActionEnvironment, and I2CAction
143 Device device{"reg1", true, "/system/chassis/motherboard/reg1",
144 std::move(i2cInterface)};
145 IDMap idMap{};
146 idMap.addDevice(device);
147 ActionEnvironment env{idMap, "reg1"};
148 I2CActionImpl action{};
149
150 // Get I2CInterface. Should throw an exception from the open() call.
151 action.getI2CInterface(env);
152 ADD_FAILURE() << "Should not have reached this line.";
153 }
154 catch (const i2c::I2CException& e)
155 {
156 EXPECT_STREQ(e.what(),
157 "I2CException: Failed to open: bus /dev/i2c-1, addr 0x70");
158 }
159 catch (...)
160 {
161 ADD_FAILURE() << "Should not have caught exception.";
162 }
163}