blob: b79e1ba8fcac04b59002ba4340e8a332359e53ab [file] [log] [blame]
Shawn McCarneyc3991f12020-04-05 13:16:06 -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 */
Shawn McCarneyc3991f12020-04-05 13:16:06 -050016#include "chassis.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050017#include "device.hpp"
18#include "id_map.hpp"
Shawn McCarney2af52892020-04-14 11:54:45 -050019#include "journal.hpp"
20#include "mock_journal.hpp"
Bob King8e2294d2020-07-14 17:41:31 +080021#include "mocked_i2c_interface.hpp"
22#include "pmbus_read_sensor_action.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050023#include "rail.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050024#include "rule.hpp"
25#include "system.hpp"
Shawn McCarneydb0b8332020-04-06 14:13:04 -050026#include "test_utils.hpp"
Shawn McCarneyc3991f12020-04-05 13:16:06 -050027
28#include <memory>
Shawn McCarneydb0b8332020-04-06 14:13:04 -050029#include <stdexcept>
Shawn McCarney2af52892020-04-14 11:54:45 -050030#include <string>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050031#include <utility>
32#include <vector>
33
Bob King8e2294d2020-07-14 17:41:31 +080034#include <gmock/gmock.h>
Shawn McCarneyc3991f12020-04-05 13:16:06 -050035#include <gtest/gtest.h>
36
37using namespace phosphor::power::regulators;
Shawn McCarneydb0b8332020-04-06 14:13:04 -050038using namespace phosphor::power::regulators::test_utils;
Shawn McCarneyc3991f12020-04-05 13:16:06 -050039
Bob King8e2294d2020-07-14 17:41:31 +080040using ::testing::A;
41using ::testing::Return;
42using ::testing::TypedEq;
43
Shawn McCarneyc3991f12020-04-05 13:16:06 -050044TEST(SystemTests, Constructor)
45{
46 // Create Rules
47 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050048 rules.emplace_back(createRule("set_voltage_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050049
50 // Create Chassis
51 std::vector<std::unique_ptr<Chassis>> chassis{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -050052 std::vector<std::unique_ptr<Device>> devices{};
53 devices.emplace_back(createDevice("reg1", {"rail1"}));
54 chassis.emplace_back(std::make_unique<Chassis>(1, std::move(devices)));
Shawn McCarneyc3991f12020-04-05 13:16:06 -050055
56 // Create System
57 System system{std::move(rules), std::move(chassis)};
58 EXPECT_EQ(system.getChassis().size(), 1);
59 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
Shawn McCarneydb0b8332020-04-06 14:13:04 -050060 EXPECT_NO_THROW(system.getIDMap().getRule("set_voltage_rule"));
61 EXPECT_NO_THROW(system.getIDMap().getDevice("reg1"));
62 EXPECT_NO_THROW(system.getIDMap().getRail("rail1"));
63 EXPECT_THROW(system.getIDMap().getRail("rail2"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -050064 EXPECT_EQ(system.getRules().size(), 1);
65 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
66}
67
Shawn McCarney5b19ea52020-06-02 18:52:56 -050068TEST(SystemTests, CloseDevices)
69{
70 // Specify an empty rules vector
71 std::vector<std::unique_ptr<Rule>> rules{};
72
73 // Create Chassis
74 std::vector<std::unique_ptr<Chassis>> chassis{};
75 chassis.emplace_back(std::make_unique<Chassis>(1));
76 chassis.emplace_back(std::make_unique<Chassis>(3));
77
78 // Create System
79 System system{std::move(rules), std::move(chassis)};
80
81 // Call closeDevices()
82 journal::clear();
83 system.closeDevices();
84 EXPECT_EQ(journal::getErrMessages().size(), 0);
85 EXPECT_EQ(journal::getInfoMessages().size(), 0);
86 std::vector<std::string> expectedDebugMessages{
87 "Closing devices in chassis 1", "Closing devices in chassis 3"};
88 EXPECT_EQ(journal::getDebugMessages(), expectedDebugMessages);
89}
90
Shawn McCarney2af52892020-04-14 11:54:45 -050091TEST(SystemTests, Configure)
92{
93 // Specify an empty rules vector
94 std::vector<std::unique_ptr<Rule>> rules{};
95
96 // Create Chassis
97 std::vector<std::unique_ptr<Chassis>> chassis{};
98 chassis.emplace_back(std::make_unique<Chassis>(1));
99 chassis.emplace_back(std::make_unique<Chassis>(3));
100
101 // Create System
102 System system{std::move(rules), std::move(chassis)};
103
104 // Call configure()
105 journal::clear();
106 system.configure();
107 EXPECT_EQ(journal::getDebugMessages().size(), 0);
108 EXPECT_EQ(journal::getErrMessages().size(), 0);
109 std::vector<std::string> expectedInfoMessages{"Configuring chassis 1",
110 "Configuring chassis 3"};
111 EXPECT_EQ(journal::getInfoMessages(), expectedInfoMessages);
112}
113
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500114TEST(SystemTests, GetChassis)
115{
116 // Specify an empty rules vector
117 std::vector<std::unique_ptr<Rule>> rules{};
118
119 // Create Chassis
120 std::vector<std::unique_ptr<Chassis>> chassis{};
121 chassis.emplace_back(std::make_unique<Chassis>(1));
122 chassis.emplace_back(std::make_unique<Chassis>(3));
123
124 // Create System
125 System system{std::move(rules), std::move(chassis)};
126 EXPECT_EQ(system.getChassis().size(), 2);
127 EXPECT_EQ(system.getChassis()[0]->getNumber(), 1);
128 EXPECT_EQ(system.getChassis()[1]->getNumber(), 3);
129}
130
131TEST(SystemTests, GetIDMap)
132{
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500133 // Create Rules
134 std::vector<std::unique_ptr<Rule>> rules{};
135 rules.emplace_back(createRule("set_voltage_rule"));
136 rules.emplace_back(createRule("read_sensors_rule"));
137
138 // Create Chassis
139 std::vector<std::unique_ptr<Chassis>> chassis{};
140 {
141 // Chassis 1
142 std::vector<std::unique_ptr<Device>> devices{};
143 devices.emplace_back(createDevice("reg1", {"rail1"}));
144 devices.emplace_back(createDevice("reg2", {"rail2a", "rail2b"}));
145 chassis.emplace_back(std::make_unique<Chassis>(1, std::move(devices)));
146 }
147 {
148 // Chassis 2
149 std::vector<std::unique_ptr<Device>> devices{};
150 devices.emplace_back(createDevice("reg3", {"rail3a", "rail3b"}));
151 devices.emplace_back(createDevice("reg4"));
152 chassis.emplace_back(std::make_unique<Chassis>(2, std::move(devices)));
153 }
154
155 // Create System
156 System system{std::move(rules), std::move(chassis)};
157 const IDMap& idMap = system.getIDMap();
158
159 // Verify all Rules are in the IDMap
160 EXPECT_NO_THROW(idMap.getRule("set_voltage_rule"));
161 EXPECT_NO_THROW(idMap.getRule("read_sensors_rule"));
162 EXPECT_THROW(idMap.getRule("set_voltage_rule2"), std::invalid_argument);
163
164 // Verify all Devices are in the IDMap
165 EXPECT_NO_THROW(idMap.getDevice("reg1"));
166 EXPECT_NO_THROW(idMap.getDevice("reg2"));
167 EXPECT_NO_THROW(idMap.getDevice("reg3"));
168 EXPECT_NO_THROW(idMap.getDevice("reg4"));
169 EXPECT_THROW(idMap.getDevice("reg5"), std::invalid_argument);
170
171 // Verify all Rails are in the IDMap
172 EXPECT_NO_THROW(idMap.getRail("rail1"));
173 EXPECT_NO_THROW(idMap.getRail("rail2a"));
174 EXPECT_NO_THROW(idMap.getRail("rail2b"));
175 EXPECT_NO_THROW(idMap.getRail("rail3a"));
176 EXPECT_NO_THROW(idMap.getRail("rail3b"));
177 EXPECT_THROW(idMap.getRail("rail4"), std::invalid_argument);
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500178}
179
180TEST(SystemTests, GetRules)
181{
182 // Create Rules
183 std::vector<std::unique_ptr<Rule>> rules{};
Shawn McCarneydb0b8332020-04-06 14:13:04 -0500184 rules.emplace_back(createRule("set_voltage_rule"));
185 rules.emplace_back(createRule("read_sensors_rule"));
Shawn McCarneyc3991f12020-04-05 13:16:06 -0500186
187 // Create Chassis
188 std::vector<std::unique_ptr<Chassis>> chassis{};
189 chassis.emplace_back(std::make_unique<Chassis>(1));
190
191 // Create System
192 System system{std::move(rules), std::move(chassis)};
193 EXPECT_EQ(system.getRules().size(), 2);
194 EXPECT_EQ(system.getRules()[0]->getID(), "set_voltage_rule");
195 EXPECT_EQ(system.getRules()[1]->getID(), "read_sensors_rule");
196}
Bob King8e2294d2020-07-14 17:41:31 +0800197
198TEST(SystemTests, MonitorSensors)
199{
200 // Create PMBusReadSensorAction
201 pmbus_utils::SensorValueType type{pmbus_utils::SensorValueType::iout};
202 uint8_t command = 0x8C;
203 pmbus_utils::SensorDataFormat format{
204 pmbus_utils::SensorDataFormat::linear_11};
205 std::optional<int8_t> exponent{};
206 std::unique_ptr<PMBusReadSensorAction> action =
207 std::make_unique<PMBusReadSensorAction>(type, command, format,
208 exponent);
209
210 // Create mock I2CInterface. A two-byte read should occur.
211 std::unique_ptr<i2c::MockedI2CInterface> i2cInterface =
212 std::make_unique<i2c::MockedI2CInterface>();
213 EXPECT_CALL(*i2cInterface, isOpen).Times(1).WillOnce(Return(true));
214 EXPECT_CALL(*i2cInterface, read(TypedEq<uint8_t>(0x8C), A<uint16_t&>()))
215 .Times(1);
216
217 // Create SensorMonitoring
218 std::vector<std::unique_ptr<Action>> actions{};
219 actions.emplace_back(std::move(action));
220 std::unique_ptr<SensorMonitoring> sensorMonitoring =
221 std::make_unique<SensorMonitoring>(std::move(actions));
222
223 // Create Rail
224 std::vector<std::unique_ptr<Rail>> rails{};
225 std::unique_ptr<Configuration> configuration{};
226 std::unique_ptr<Rail> rail = std::make_unique<Rail>(
227 "vdd0", std::move(configuration), std::move(sensorMonitoring));
228 rails.emplace_back(std::move(rail));
229
230 // Create Device
231 std::unique_ptr<PresenceDetection> presenceDetection{};
232 std::unique_ptr<Configuration> deviceConfiguration{};
233 std::unique_ptr<Device> device = std::make_unique<Device>(
234 "reg1", true, "/system/chassis/motherboard/reg1",
235 std::move(i2cInterface), std::move(presenceDetection),
236 std::move(deviceConfiguration), std::move(rails));
237
238 // Create Chassis
239 std::vector<std::unique_ptr<Device>> devices{};
240 devices.emplace_back(std::move(device));
241 std::unique_ptr<Chassis> chassis =
242 std::make_unique<Chassis>(1, std::move(devices));
243
244 // Create System that contains Chassis
245 std::vector<std::unique_ptr<Rule>> rules{};
246 std::vector<std::unique_ptr<Chassis>> chassisVec{};
247 chassisVec.emplace_back(std::move(chassis));
248 System system{std::move(rules), std::move(chassisVec)};
249
250 // Call monitorSensors()
251 journal::clear();
252 system.monitorSensors();
253 EXPECT_EQ(journal::getDebugMessages().size(), 0);
254 EXPECT_EQ(journal::getErrMessages().size(), 0);
255}