blob: 79c3b92655f212541a8954ea9bd160e28cb6f56e [file] [log] [blame]
Shawn McCarneybc47c1b2020-03-10 15:38:07 -05001/**
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.hpp"
Bob King833b8e02020-06-11 14:56:38 +080017#include "chassis.hpp"
18#include "configuration.hpp"
19#include "device.hpp"
20#include "i2c_interface.hpp"
21#include "journal.hpp"
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050022#include "mock_action.hpp"
Bob King833b8e02020-06-11 14:56:38 +080023#include "mock_journal.hpp"
24#include "mocked_i2c_interface.hpp"
25#include "pmbus_read_sensor_action.hpp"
26#include "pmbus_utils.hpp"
27#include "presence_detection.hpp"
28#include "rail.hpp"
29#include "rule.hpp"
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050030#include "sensor_monitoring.hpp"
Bob King833b8e02020-06-11 14:56:38 +080031#include "system.hpp"
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050032
Bob King833b8e02020-06-11 14:56:38 +080033#include <cstdint>
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050034#include <memory>
Bob King833b8e02020-06-11 14:56:38 +080035#include <optional>
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050036#include <utility>
37#include <vector>
38
Bob King833b8e02020-06-11 14:56:38 +080039#include <gmock/gmock.h>
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050040#include <gtest/gtest.h>
41
42using namespace phosphor::power::regulators;
Bob King833b8e02020-06-11 14:56:38 +080043using namespace phosphor::power::regulators::pmbus_utils;
44
45using ::testing::A;
46using ::testing::Return;
47using ::testing::Throw;
48using ::testing::TypedEq;
Shawn McCarneybc47c1b2020-03-10 15:38:07 -050049
50TEST(SensorMonitoringTests, Constructor)
51{
52 std::vector<std::unique_ptr<Action>> actions{};
53 actions.push_back(std::make_unique<MockAction>());
54
55 SensorMonitoring sensorMonitoring(std::move(actions));
56 EXPECT_EQ(sensorMonitoring.getActions().size(), 1);
57}
58
59TEST(SensorMonitoringTests, Execute)
60{
Bob King833b8e02020-06-11 14:56:38 +080061 // Test where works
62 {
63 // Create PMBusReadSensorAction
64 pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
65 uint8_t command = 0x8C;
66 pmbus_utils::SensorDataFormat format{
67 pmbus_utils::SensorDataFormat::linear_11};
68 std::optional<int8_t> exponent{};
69 std::unique_ptr<PMBusReadSensorAction> action =
70 std::make_unique<PMBusReadSensorAction>(type, command, format,
71 exponent);
72
73 // Create mock I2CInterface.
74 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
75 std::make_unique<i2c::MockedI2CInterface>();
76 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
77 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
78 .Times(1);
79
80 // Create SensorMonitoring
81 std::vector<std::unique_ptr<Action>> actions{};
82 actions.emplace_back(std::move(action));
83 std::unique_ptr<SensorMonitoring> sensorMonitoring =
84 std::make_unique<SensorMonitoring>(std::move(actions));
85 SensorMonitoring* sensorMonitoringPtr = sensorMonitoring.get();
86
87 // Create Rail that contains sensorMonitoring
88 std::unique_ptr<Configuration> configuration{};
89 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
90 "vio2", std::move(configuration), std::move(sensorMonitoring));
91 Rail* railPtr = rail.get();
92
93 // Create Device that contains Rail
94 std::unique_ptr<PresenceDetection> presenceDetection{};
95 std::unique_ptr<Configuration> deviceConfiguration{};
96 std::vector<std::unique_ptr<Rail>> rails{};
97 rails.emplace_back(std::move(rail));
98 std::unique_ptr<Device> device = std::make_unique<Device>(
99 "reg1", true, "/system/chassis/motherboard/reg1",
100 std::move(i2cInterface), std::move(presenceDetection),
101 std::move(deviceConfiguration), std::move(rails));
102 Device* devicePtr = device.get();
103
104 // Create Chassis that contains Device
105 std::vector<std::unique_ptr<Device>> devices{};
106 devices.emplace_back(std::move(device));
107 std::unique_ptr<Chassis> chassis =
108 std::make_unique<Chassis>(1, std::move(devices));
109 Chassis* chassisPtr = chassis.get();
110
111 // Create System that contains Chassis
112 std::vector<std::unique_ptr<Rule>> rules{};
113 std::vector<std::unique_ptr<Chassis>> chassisVec{};
114 chassisVec.emplace_back(std::move(chassis));
115 System system{std::move(rules), std::move(chassisVec)};
116
117 // Execute sensorMonitoring
118 journal::clear();
119 sensorMonitoringPtr->execute(system, *chassisPtr, *devicePtr, *railPtr);
120 EXPECT_EQ(journal::getDebugMessages().size(), 0);
121 EXPECT_EQ(journal::getErrMessages().size(), 0);
122 }
123
124 // Test where fails
125 {
126 // Create PMBusReadSensorAction
127 pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
128 uint8_t command = 0x8C;
129 pmbus_utils::SensorDataFormat format{
130 pmbus_utils::SensorDataFormat::linear_11};
131 std::optional<int8_t> exponent{};
132 std::unique_ptr<PMBusReadSensorAction> action =
133 std::make_unique<PMBusReadSensorAction>(type, command, format,
134 exponent);
135
136 // Create mock I2CInterface.
137 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
138 std::make_unique<i2c::MockedI2CInterface>();
139 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
140 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
141 .Times(1)
142 .WillOnce(Throw(
143 i2c::I2CException{"Failed to write byte", "/dev/i2c-1", 0x70}));
144
145 // Create SensorMonitoring
146 std::vector<std::unique_ptr<Action>> actions{};
147 actions.emplace_back(std::move(action));
148 std::unique_ptr<SensorMonitoring> sensorMonitoring =
149 std::make_unique<SensorMonitoring>(std::move(actions));
150 SensorMonitoring* sensorMonitoringPtr = sensorMonitoring.get();
151
152 // Create Rail that contains sensorMonitoring
153 std::unique_ptr<Configuration> configuration{};
154 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
155 "vio2", std::move(configuration), std::move(sensorMonitoring));
156 Rail* railPtr = rail.get();
157
158 // Create Device that contains Rail
159 std::unique_ptr<PresenceDetection> presenceDetection{};
160 std::unique_ptr<Configuration> deviceConfiguration{};
161 std::vector<std::unique_ptr<Rail>> rails{};
162 rails.emplace_back(std::move(rail));
163 std::unique_ptr<Device> device = std::make_unique<Device>(
164 "reg1", true, "/system/chassis/motherboard/reg1",
165 std::move(i2cInterface), std::move(presenceDetection),
166 std::move(deviceConfiguration), std::move(rails));
167 Device* devicePtr = device.get();
168
169 // Create Chassis that contains Device
170 std::vector<std::unique_ptr<Device>> devices{};
171 devices.emplace_back(std::move(device));
172 std::unique_ptr<Chassis> chassis =
173 std::make_unique<Chassis>(1, std::move(devices));
174 Chassis* chassisPtr = chassis.get();
175
176 // Create System that contains Chassis
177 std::vector<std::unique_ptr<Rule>> rules{};
178 std::vector<std::unique_ptr<Chassis>> chassisVec{};
179 chassisVec.emplace_back(std::move(chassis));
180 System system{std::move(rules), std::move(chassisVec)};
181
182 // Execute sensorMonitoring
183 journal::clear();
184 sensorMonitoringPtr->execute(system, *chassisPtr, *devicePtr, *railPtr);
185 EXPECT_EQ(journal::getDebugMessages().size(), 0);
186 std::vector<std::string> expectedErrMessages{
187 "I2CException: Failed to write byte: bus /dev/i2c-1, addr 0x70",
188 "ActionError: pmbus_read_sensor: { type: iout, command: 0x8C, "
189 "format: linear_11 }",
190 "Unable to monitor sensors for rail vio2"};
191 EXPECT_EQ(journal::getErrMessages(), expectedErrMessages);
192 }
Shawn McCarneybc47c1b2020-03-10 15:38:07 -0500193}
194
195TEST(SensorMonitoringTests, GetActions)
196{
197 std::vector<std::unique_ptr<Action>> actions{};
198
199 MockAction* action1 = new MockAction{};
200 actions.push_back(std::unique_ptr<MockAction>{action1});
201
202 MockAction* action2 = new MockAction{};
203 actions.push_back(std::unique_ptr<MockAction>{action2});
204
205 SensorMonitoring sensorMonitoring(std::move(actions));
206 EXPECT_EQ(sensorMonitoring.getActions().size(), 2);
207 EXPECT_EQ(sensorMonitoring.getActions()[0].get(), action1);
208 EXPECT_EQ(sensorMonitoring.getActions()[1].get(), action2);
209}