1d6e9bfe2SShawn McCarney /**
2d6e9bfe2SShawn McCarney * Copyright © 2024 IBM Corporation
3d6e9bfe2SShawn McCarney *
4d6e9bfe2SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License");
5d6e9bfe2SShawn McCarney * you may not use this file except in compliance with the License.
6d6e9bfe2SShawn McCarney * You may obtain a copy of the License at
7d6e9bfe2SShawn McCarney *
8d6e9bfe2SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0
9d6e9bfe2SShawn McCarney *
10d6e9bfe2SShawn McCarney * Unless required by applicable law or agreed to in writing, software
11d6e9bfe2SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS,
12d6e9bfe2SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13d6e9bfe2SShawn McCarney * See the License for the specific language governing permissions and
14d6e9bfe2SShawn McCarney * limitations under the License.
15d6e9bfe2SShawn McCarney */
16d6e9bfe2SShawn McCarney
1724956598SShawn McCarney #include "mock_device.hpp"
1824956598SShawn McCarney #include "mock_services.hpp"
19d6e9bfe2SShawn McCarney #include "rail.hpp"
20d6e9bfe2SShawn McCarney
21d6e9bfe2SShawn McCarney #include <cstdint>
2224956598SShawn McCarney #include <map>
23d6e9bfe2SShawn McCarney #include <optional>
24d6e9bfe2SShawn McCarney #include <string>
2524956598SShawn McCarney #include <vector>
26d6e9bfe2SShawn McCarney
2724956598SShawn McCarney #include <gmock/gmock.h>
28d6e9bfe2SShawn McCarney #include <gtest/gtest.h>
29d6e9bfe2SShawn McCarney
30d6e9bfe2SShawn McCarney using namespace phosphor::power::sequencer;
31d6e9bfe2SShawn McCarney
3224956598SShawn McCarney using ::testing::Return;
3324956598SShawn McCarney using ::testing::Throw;
3424956598SShawn McCarney
TEST(GPIOTests,Initialization)35d6e9bfe2SShawn McCarney TEST(GPIOTests, Initialization)
36d6e9bfe2SShawn McCarney {
37d6e9bfe2SShawn McCarney // Default initialization
38d6e9bfe2SShawn McCarney {
39d6e9bfe2SShawn McCarney GPIO gpio;
40d6e9bfe2SShawn McCarney EXPECT_EQ(gpio.line, 0);
41d6e9bfe2SShawn McCarney EXPECT_FALSE(gpio.activeLow);
42d6e9bfe2SShawn McCarney }
43d6e9bfe2SShawn McCarney
44d6e9bfe2SShawn McCarney // Explicit initialization
45d6e9bfe2SShawn McCarney {
46d6e9bfe2SShawn McCarney GPIO gpio{48, true};
47d6e9bfe2SShawn McCarney EXPECT_EQ(gpio.line, 48);
48d6e9bfe2SShawn McCarney EXPECT_TRUE(gpio.activeLow);
49d6e9bfe2SShawn McCarney }
50d6e9bfe2SShawn McCarney }
51d6e9bfe2SShawn McCarney
TEST(RailTests,Constructor)52d6e9bfe2SShawn McCarney TEST(RailTests, Constructor)
53d6e9bfe2SShawn McCarney {
54d6e9bfe2SShawn McCarney // Test where succeeds: No optional parameters have values
55d6e9bfe2SShawn McCarney {
5616e493afSShawn McCarney std::string name{"12.0V"};
57d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
58d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
5916e493afSShawn McCarney bool isPowerSupplyRail{true};
60d6e9bfe2SShawn McCarney bool checkStatusVout{false};
619ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
62d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
6316e493afSShawn McCarney Rail rail{name,
6416e493afSShawn McCarney presence,
6516e493afSShawn McCarney page,
6616e493afSShawn McCarney isPowerSupplyRail,
6716e493afSShawn McCarney checkStatusVout,
689ec0d43dSShawn McCarney compareVoltageToLimit,
69d6e9bfe2SShawn McCarney gpio};
70d6e9bfe2SShawn McCarney
7116e493afSShawn McCarney EXPECT_EQ(rail.getName(), "12.0V");
72d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getPresence().has_value());
73d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getPage().has_value());
7416e493afSShawn McCarney EXPECT_TRUE(rail.isPowerSupplyRail());
75d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getCheckStatusVout());
769ec0d43dSShawn McCarney EXPECT_FALSE(rail.getCompareVoltageToLimit());
77d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getGPIO().has_value());
78d6e9bfe2SShawn McCarney }
79d6e9bfe2SShawn McCarney
80d6e9bfe2SShawn McCarney // Test where succeeds: All optional parameters have values
81d6e9bfe2SShawn McCarney {
82d6e9bfe2SShawn McCarney std::string name{"VCS_CPU1"};
83d6e9bfe2SShawn McCarney std::optional<std::string> presence{
84d6e9bfe2SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1"};
85d6e9bfe2SShawn McCarney std::optional<uint8_t> page{11};
8616e493afSShawn McCarney bool isPowerSupplyRail{false};
87d6e9bfe2SShawn McCarney bool checkStatusVout{true};
889ec0d43dSShawn McCarney bool compareVoltageToLimit{true};
89d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{GPIO(60, true)};
9016e493afSShawn McCarney Rail rail{name,
9116e493afSShawn McCarney presence,
9216e493afSShawn McCarney page,
9316e493afSShawn McCarney isPowerSupplyRail,
9416e493afSShawn McCarney checkStatusVout,
959ec0d43dSShawn McCarney compareVoltageToLimit,
96d6e9bfe2SShawn McCarney gpio};
97d6e9bfe2SShawn McCarney
98d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getName(), "VCS_CPU1");
99d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getPresence().has_value());
100d6e9bfe2SShawn McCarney EXPECT_EQ(
101d6e9bfe2SShawn McCarney rail.getPresence().value(),
102d6e9bfe2SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu1");
103d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getPage().has_value());
104d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getPage().value(), 11);
10516e493afSShawn McCarney EXPECT_FALSE(rail.isPowerSupplyRail());
106d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getCheckStatusVout());
1079ec0d43dSShawn McCarney EXPECT_TRUE(rail.getCompareVoltageToLimit());
108d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getGPIO().has_value());
109d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getGPIO().value().line, 60);
110d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getGPIO().value().activeLow);
111d6e9bfe2SShawn McCarney }
112d6e9bfe2SShawn McCarney
113d6e9bfe2SShawn McCarney // Test where fails: checkStatusVout is true and page has no value
114d6e9bfe2SShawn McCarney {
115d6e9bfe2SShawn McCarney std::string name{"VDD1"};
116d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
117d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
11816e493afSShawn McCarney bool isPowerSupplyRail{false};
119d6e9bfe2SShawn McCarney bool checkStatusVout{true};
1209ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
121d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
12216e493afSShawn McCarney EXPECT_THROW((Rail{name, presence, page, isPowerSupplyRail,
1239ec0d43dSShawn McCarney checkStatusVout, compareVoltageToLimit, gpio}),
124d6e9bfe2SShawn McCarney std::invalid_argument);
125d6e9bfe2SShawn McCarney }
126d6e9bfe2SShawn McCarney
1279ec0d43dSShawn McCarney // Test where fails: compareVoltageToLimit is true and page has no value
128d6e9bfe2SShawn McCarney {
129d6e9bfe2SShawn McCarney std::string name{"VDD1"};
130d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
131d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
13216e493afSShawn McCarney bool isPowerSupplyRail{false};
133d6e9bfe2SShawn McCarney bool checkStatusVout{false};
1349ec0d43dSShawn McCarney bool compareVoltageToLimit{true};
135d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
13616e493afSShawn McCarney EXPECT_THROW((Rail{name, presence, page, isPowerSupplyRail,
1379ec0d43dSShawn McCarney checkStatusVout, compareVoltageToLimit, gpio}),
138d6e9bfe2SShawn McCarney std::invalid_argument);
139d6e9bfe2SShawn McCarney }
140d6e9bfe2SShawn McCarney }
141d6e9bfe2SShawn McCarney
TEST(RailTests,GetName)142d6e9bfe2SShawn McCarney TEST(RailTests, GetName)
143d6e9bfe2SShawn McCarney {
144d6e9bfe2SShawn McCarney std::string name{"VDD2"};
145d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
146d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
14716e493afSShawn McCarney bool isPowerSupplyRail{false};
148d6e9bfe2SShawn McCarney bool checkStatusVout{false};
1499ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
150d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
15116e493afSShawn McCarney Rail rail{name,
15216e493afSShawn McCarney presence,
15316e493afSShawn McCarney page,
15416e493afSShawn McCarney isPowerSupplyRail,
15516e493afSShawn McCarney checkStatusVout,
1569ec0d43dSShawn McCarney compareVoltageToLimit,
157d6e9bfe2SShawn McCarney gpio};
158d6e9bfe2SShawn McCarney
159d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getName(), "VDD2");
160d6e9bfe2SShawn McCarney }
161d6e9bfe2SShawn McCarney
TEST(RailTests,GetPresence)162d6e9bfe2SShawn McCarney TEST(RailTests, GetPresence)
163d6e9bfe2SShawn McCarney {
164d6e9bfe2SShawn McCarney std::string name{"VDDR2"};
165d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
16616e493afSShawn McCarney bool isPowerSupplyRail{false};
167d6e9bfe2SShawn McCarney bool checkStatusVout{false};
1689ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
169d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
170d6e9bfe2SShawn McCarney
171d6e9bfe2SShawn McCarney // Test where presence has no value
172d6e9bfe2SShawn McCarney {
173d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
17416e493afSShawn McCarney Rail rail{name,
17516e493afSShawn McCarney presence,
17616e493afSShawn McCarney page,
17716e493afSShawn McCarney isPowerSupplyRail,
17816e493afSShawn McCarney checkStatusVout,
1799ec0d43dSShawn McCarney compareVoltageToLimit,
180d6e9bfe2SShawn McCarney gpio};
181d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getPresence().has_value());
182d6e9bfe2SShawn McCarney }
183d6e9bfe2SShawn McCarney
184d6e9bfe2SShawn McCarney // Test where presence has a value
185d6e9bfe2SShawn McCarney {
186d6e9bfe2SShawn McCarney std::optional<std::string> presence{
187d6e9bfe2SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm2"};
18816e493afSShawn McCarney Rail rail{name,
18916e493afSShawn McCarney presence,
19016e493afSShawn McCarney page,
19116e493afSShawn McCarney isPowerSupplyRail,
19216e493afSShawn McCarney checkStatusVout,
1939ec0d43dSShawn McCarney compareVoltageToLimit,
194d6e9bfe2SShawn McCarney gpio};
195d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getPresence().has_value());
196d6e9bfe2SShawn McCarney EXPECT_EQ(
197d6e9bfe2SShawn McCarney rail.getPresence().value(),
198d6e9bfe2SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/dimm2");
199d6e9bfe2SShawn McCarney }
200d6e9bfe2SShawn McCarney }
201d6e9bfe2SShawn McCarney
TEST(RailTests,GetPage)202d6e9bfe2SShawn McCarney TEST(RailTests, GetPage)
203d6e9bfe2SShawn McCarney {
204d6e9bfe2SShawn McCarney std::string name{"VDD2"};
205d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
20616e493afSShawn McCarney bool isPowerSupplyRail{false};
207d6e9bfe2SShawn McCarney bool checkStatusVout{false};
2089ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
209d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
210d6e9bfe2SShawn McCarney
211d6e9bfe2SShawn McCarney // Test where page has no value
212d6e9bfe2SShawn McCarney {
213d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
21416e493afSShawn McCarney Rail rail{name,
21516e493afSShawn McCarney presence,
21616e493afSShawn McCarney page,
21716e493afSShawn McCarney isPowerSupplyRail,
21816e493afSShawn McCarney checkStatusVout,
2199ec0d43dSShawn McCarney compareVoltageToLimit,
220d6e9bfe2SShawn McCarney gpio};
221d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getPage().has_value());
222d6e9bfe2SShawn McCarney }
223d6e9bfe2SShawn McCarney
224d6e9bfe2SShawn McCarney // Test where page has a value
225d6e9bfe2SShawn McCarney {
226d6e9bfe2SShawn McCarney std::optional<uint8_t> page{7};
22716e493afSShawn McCarney Rail rail{name,
22816e493afSShawn McCarney presence,
22916e493afSShawn McCarney page,
23016e493afSShawn McCarney isPowerSupplyRail,
23116e493afSShawn McCarney checkStatusVout,
2329ec0d43dSShawn McCarney compareVoltageToLimit,
233d6e9bfe2SShawn McCarney gpio};
234d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getPage().has_value());
235d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getPage().value(), 7);
236d6e9bfe2SShawn McCarney }
237d6e9bfe2SShawn McCarney }
238d6e9bfe2SShawn McCarney
TEST(RailTests,IsPowerSupplyRail)23916e493afSShawn McCarney TEST(RailTests, IsPowerSupplyRail)
24016e493afSShawn McCarney {
24116e493afSShawn McCarney std::string name{"12.0V"};
24216e493afSShawn McCarney std::optional<std::string> presence{};
24316e493afSShawn McCarney std::optional<uint8_t> page{};
24416e493afSShawn McCarney bool isPowerSupplyRail{true};
24516e493afSShawn McCarney bool checkStatusVout{false};
2469ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
24716e493afSShawn McCarney std::optional<GPIO> gpio{};
24816e493afSShawn McCarney Rail rail{name,
24916e493afSShawn McCarney presence,
25016e493afSShawn McCarney page,
25116e493afSShawn McCarney isPowerSupplyRail,
25216e493afSShawn McCarney checkStatusVout,
2539ec0d43dSShawn McCarney compareVoltageToLimit,
25416e493afSShawn McCarney gpio};
25516e493afSShawn McCarney
25616e493afSShawn McCarney EXPECT_TRUE(rail.isPowerSupplyRail());
25716e493afSShawn McCarney }
25816e493afSShawn McCarney
TEST(RailTests,GetCheckStatusVout)259d6e9bfe2SShawn McCarney TEST(RailTests, GetCheckStatusVout)
260d6e9bfe2SShawn McCarney {
261d6e9bfe2SShawn McCarney std::string name{"VDD2"};
262d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
263d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
26416e493afSShawn McCarney bool isPowerSupplyRail{false};
265d6e9bfe2SShawn McCarney bool checkStatusVout{false};
2669ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
267d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
26816e493afSShawn McCarney Rail rail{name,
26916e493afSShawn McCarney presence,
27016e493afSShawn McCarney page,
27116e493afSShawn McCarney isPowerSupplyRail,
27216e493afSShawn McCarney checkStatusVout,
2739ec0d43dSShawn McCarney compareVoltageToLimit,
274d6e9bfe2SShawn McCarney gpio};
275d6e9bfe2SShawn McCarney
276d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getCheckStatusVout());
277d6e9bfe2SShawn McCarney }
278d6e9bfe2SShawn McCarney
TEST(RailTests,GetCompareVoltageToLimit)2799ec0d43dSShawn McCarney TEST(RailTests, GetCompareVoltageToLimit)
280d6e9bfe2SShawn McCarney {
281d6e9bfe2SShawn McCarney std::string name{"VDD2"};
282d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
283d6e9bfe2SShawn McCarney std::optional<uint8_t> page{13};
28416e493afSShawn McCarney bool isPowerSupplyRail{false};
285d6e9bfe2SShawn McCarney bool checkStatusVout{false};
2869ec0d43dSShawn McCarney bool compareVoltageToLimit{true};
287d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
28816e493afSShawn McCarney Rail rail{name,
28916e493afSShawn McCarney presence,
29016e493afSShawn McCarney page,
29116e493afSShawn McCarney isPowerSupplyRail,
29216e493afSShawn McCarney checkStatusVout,
2939ec0d43dSShawn McCarney compareVoltageToLimit,
294d6e9bfe2SShawn McCarney gpio};
295d6e9bfe2SShawn McCarney
2969ec0d43dSShawn McCarney EXPECT_TRUE(rail.getCompareVoltageToLimit());
297d6e9bfe2SShawn McCarney }
298d6e9bfe2SShawn McCarney
TEST(RailTests,GetGPIO)299d6e9bfe2SShawn McCarney TEST(RailTests, GetGPIO)
300d6e9bfe2SShawn McCarney {
301d6e9bfe2SShawn McCarney std::string name{"VDD2"};
302d6e9bfe2SShawn McCarney std::optional<std::string> presence{};
303d6e9bfe2SShawn McCarney std::optional<uint8_t> page{};
30416e493afSShawn McCarney bool isPowerSupplyRail{false};
305d6e9bfe2SShawn McCarney bool checkStatusVout{false};
3069ec0d43dSShawn McCarney bool compareVoltageToLimit{false};
307d6e9bfe2SShawn McCarney
308d6e9bfe2SShawn McCarney // Test where gpio has no value
309d6e9bfe2SShawn McCarney {
310d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{};
31116e493afSShawn McCarney Rail rail{name,
31216e493afSShawn McCarney presence,
31316e493afSShawn McCarney page,
31416e493afSShawn McCarney isPowerSupplyRail,
31516e493afSShawn McCarney checkStatusVout,
3169ec0d43dSShawn McCarney compareVoltageToLimit,
317d6e9bfe2SShawn McCarney gpio};
318d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getGPIO().has_value());
319d6e9bfe2SShawn McCarney }
320d6e9bfe2SShawn McCarney
321d6e9bfe2SShawn McCarney // Test where gpio has a value
322d6e9bfe2SShawn McCarney {
323d6e9bfe2SShawn McCarney std::optional<GPIO> gpio{GPIO(12, false)};
32416e493afSShawn McCarney Rail rail{name,
32516e493afSShawn McCarney presence,
32616e493afSShawn McCarney page,
32716e493afSShawn McCarney isPowerSupplyRail,
32816e493afSShawn McCarney checkStatusVout,
3299ec0d43dSShawn McCarney compareVoltageToLimit,
330d6e9bfe2SShawn McCarney gpio};
331d6e9bfe2SShawn McCarney EXPECT_TRUE(rail.getGPIO().has_value());
332d6e9bfe2SShawn McCarney EXPECT_EQ(rail.getGPIO().value().line, 12);
333d6e9bfe2SShawn McCarney EXPECT_FALSE(rail.getGPIO().value().activeLow);
334d6e9bfe2SShawn McCarney }
335d6e9bfe2SShawn McCarney }
33624956598SShawn McCarney
TEST(RailTests,IsPresent)33724956598SShawn McCarney TEST(RailTests, IsPresent)
33824956598SShawn McCarney {
33924956598SShawn McCarney std::string name{"VDD2"};
34024956598SShawn McCarney std::optional<uint8_t> page{};
34124956598SShawn McCarney bool isPowerSupplyRail{false};
34224956598SShawn McCarney bool checkStatusVout{false};
34324956598SShawn McCarney bool compareVoltageToLimit{false};
34424956598SShawn McCarney std::optional<GPIO> gpio{};
34524956598SShawn McCarney
34624956598SShawn McCarney // Test where inventory path not specified; always returns true
34724956598SShawn McCarney {
34824956598SShawn McCarney std::optional<std::string> presence{};
34924956598SShawn McCarney Rail rail{name,
35024956598SShawn McCarney presence,
35124956598SShawn McCarney page,
35224956598SShawn McCarney isPowerSupplyRail,
35324956598SShawn McCarney checkStatusVout,
35424956598SShawn McCarney compareVoltageToLimit,
35524956598SShawn McCarney gpio};
35624956598SShawn McCarney
35724956598SShawn McCarney MockServices services{};
35824956598SShawn McCarney EXPECT_CALL(services, isPresent).Times(0);
35924956598SShawn McCarney
36024956598SShawn McCarney EXPECT_TRUE(rail.isPresent(services));
36124956598SShawn McCarney }
36224956598SShawn McCarney
36324956598SShawn McCarney // Test where inventory path is not present
36424956598SShawn McCarney {
36524956598SShawn McCarney std::optional<std::string> presence{
36624956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
36724956598SShawn McCarney Rail rail{name,
36824956598SShawn McCarney presence,
36924956598SShawn McCarney page,
37024956598SShawn McCarney isPowerSupplyRail,
37124956598SShawn McCarney checkStatusVout,
37224956598SShawn McCarney compareVoltageToLimit,
37324956598SShawn McCarney gpio};
37424956598SShawn McCarney
37524956598SShawn McCarney MockServices services{};
37624956598SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
37724956598SShawn McCarney .Times(1)
37824956598SShawn McCarney .WillOnce(Return(false));
37924956598SShawn McCarney
38024956598SShawn McCarney EXPECT_FALSE(rail.isPresent(services));
38124956598SShawn McCarney }
38224956598SShawn McCarney
38324956598SShawn McCarney // Test where inventory path is present
38424956598SShawn McCarney {
38524956598SShawn McCarney std::optional<std::string> presence{
38624956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
38724956598SShawn McCarney Rail rail{name,
38824956598SShawn McCarney presence,
38924956598SShawn McCarney page,
39024956598SShawn McCarney isPowerSupplyRail,
39124956598SShawn McCarney checkStatusVout,
39224956598SShawn McCarney compareVoltageToLimit,
39324956598SShawn McCarney gpio};
39424956598SShawn McCarney
39524956598SShawn McCarney MockServices services{};
39624956598SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
39724956598SShawn McCarney .Times(1)
39824956598SShawn McCarney .WillOnce(Return(true));
39924956598SShawn McCarney
40024956598SShawn McCarney EXPECT_TRUE(rail.isPresent(services));
40124956598SShawn McCarney }
40224956598SShawn McCarney
40324956598SShawn McCarney // Test where exception occurs trying to get presence
40424956598SShawn McCarney {
40524956598SShawn McCarney std::optional<std::string> presence{
40624956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
40724956598SShawn McCarney Rail rail{name,
40824956598SShawn McCarney presence,
40924956598SShawn McCarney page,
41024956598SShawn McCarney isPowerSupplyRail,
41124956598SShawn McCarney checkStatusVout,
41224956598SShawn McCarney compareVoltageToLimit,
41324956598SShawn McCarney gpio};
41424956598SShawn McCarney
41524956598SShawn McCarney MockServices services{};
41624956598SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
41724956598SShawn McCarney .Times(1)
41824956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"Invalid object path"}));
41924956598SShawn McCarney
42024956598SShawn McCarney try
42124956598SShawn McCarney {
42224956598SShawn McCarney rail.isPresent(services);
42324956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
42424956598SShawn McCarney }
42524956598SShawn McCarney catch (const std::exception& e)
42624956598SShawn McCarney {
42724956598SShawn McCarney EXPECT_STREQ(
42824956598SShawn McCarney e.what(),
42924956598SShawn McCarney "Unable to determine presence of rail VDD2 using "
43024956598SShawn McCarney "inventory path "
43124956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2: "
43224956598SShawn McCarney "Invalid object path");
43324956598SShawn McCarney }
43424956598SShawn McCarney }
43524956598SShawn McCarney }
43624956598SShawn McCarney
TEST(RailTests,GetStatusWord)43724956598SShawn McCarney TEST(RailTests, GetStatusWord)
43824956598SShawn McCarney {
43924956598SShawn McCarney std::string name{"VDD2"};
44024956598SShawn McCarney std::optional<std::string> presence{};
44124956598SShawn McCarney bool isPowerSupplyRail{false};
44224956598SShawn McCarney bool checkStatusVout{false};
44324956598SShawn McCarney bool compareVoltageToLimit{false};
44424956598SShawn McCarney std::optional<GPIO> gpio{};
44524956598SShawn McCarney
44624956598SShawn McCarney // Test where page was not specified: Throws exception
44724956598SShawn McCarney {
44824956598SShawn McCarney std::optional<uint8_t> page{};
44924956598SShawn McCarney Rail rail{name,
45024956598SShawn McCarney presence,
45124956598SShawn McCarney page,
45224956598SShawn McCarney isPowerSupplyRail,
45324956598SShawn McCarney checkStatusVout,
45424956598SShawn McCarney compareVoltageToLimit,
45524956598SShawn McCarney gpio};
45624956598SShawn McCarney
45724956598SShawn McCarney MockDevice device{};
45824956598SShawn McCarney EXPECT_CALL(device, getStatusWord).Times(0);
45924956598SShawn McCarney
46024956598SShawn McCarney try
46124956598SShawn McCarney {
46224956598SShawn McCarney rail.getStatusWord(device);
46324956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
46424956598SShawn McCarney }
46524956598SShawn McCarney catch (const std::exception& e)
46624956598SShawn McCarney {
46724956598SShawn McCarney EXPECT_STREQ(e.what(),
46824956598SShawn McCarney "Unable to read STATUS_WORD value for rail VDD2: "
46924956598SShawn McCarney "No PAGE number defined for rail VDD2");
47024956598SShawn McCarney }
47124956598SShawn McCarney }
47224956598SShawn McCarney
47324956598SShawn McCarney // Test where value read successfully
47424956598SShawn McCarney {
47524956598SShawn McCarney std::optional<uint8_t> page{2};
47624956598SShawn McCarney Rail rail{name,
47724956598SShawn McCarney presence,
47824956598SShawn McCarney page,
47924956598SShawn McCarney isPowerSupplyRail,
48024956598SShawn McCarney checkStatusVout,
48124956598SShawn McCarney compareVoltageToLimit,
48224956598SShawn McCarney gpio};
48324956598SShawn McCarney
48424956598SShawn McCarney MockDevice device{};
48524956598SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
48624956598SShawn McCarney
48724956598SShawn McCarney EXPECT_EQ(rail.getStatusWord(device), 0xbeef);
48824956598SShawn McCarney }
48924956598SShawn McCarney
49024956598SShawn McCarney // Test where exception occurs trying to read value
49124956598SShawn McCarney {
49224956598SShawn McCarney std::optional<uint8_t> page{2};
49324956598SShawn McCarney Rail rail{name,
49424956598SShawn McCarney presence,
49524956598SShawn McCarney page,
49624956598SShawn McCarney isPowerSupplyRail,
49724956598SShawn McCarney checkStatusVout,
49824956598SShawn McCarney compareVoltageToLimit,
49924956598SShawn McCarney gpio};
50024956598SShawn McCarney
50124956598SShawn McCarney MockDevice device{};
50224956598SShawn McCarney EXPECT_CALL(device, getStatusWord(2))
50324956598SShawn McCarney .Times(1)
50424956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
50524956598SShawn McCarney
50624956598SShawn McCarney try
50724956598SShawn McCarney {
50824956598SShawn McCarney rail.getStatusWord(device);
50924956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
51024956598SShawn McCarney }
51124956598SShawn McCarney catch (const std::exception& e)
51224956598SShawn McCarney {
51324956598SShawn McCarney EXPECT_STREQ(e.what(),
51424956598SShawn McCarney "Unable to read STATUS_WORD value for rail VDD2: "
51524956598SShawn McCarney "File does not exist");
51624956598SShawn McCarney }
51724956598SShawn McCarney }
51824956598SShawn McCarney }
51924956598SShawn McCarney
TEST(RailTests,GetStatusVout)52024956598SShawn McCarney TEST(RailTests, GetStatusVout)
52124956598SShawn McCarney {
52224956598SShawn McCarney std::string name{"VDD2"};
52324956598SShawn McCarney std::optional<std::string> presence{};
52424956598SShawn McCarney bool isPowerSupplyRail{false};
52524956598SShawn McCarney bool checkStatusVout{false};
52624956598SShawn McCarney bool compareVoltageToLimit{false};
52724956598SShawn McCarney std::optional<GPIO> gpio{};
52824956598SShawn McCarney
52924956598SShawn McCarney // Test where page was not specified: Throws exception
53024956598SShawn McCarney {
53124956598SShawn McCarney std::optional<uint8_t> page{};
53224956598SShawn McCarney Rail rail{name,
53324956598SShawn McCarney presence,
53424956598SShawn McCarney page,
53524956598SShawn McCarney isPowerSupplyRail,
53624956598SShawn McCarney checkStatusVout,
53724956598SShawn McCarney compareVoltageToLimit,
53824956598SShawn McCarney gpio};
53924956598SShawn McCarney
54024956598SShawn McCarney MockDevice device{};
54124956598SShawn McCarney EXPECT_CALL(device, getStatusVout).Times(0);
54224956598SShawn McCarney
54324956598SShawn McCarney try
54424956598SShawn McCarney {
54524956598SShawn McCarney rail.getStatusVout(device);
54624956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
54724956598SShawn McCarney }
54824956598SShawn McCarney catch (const std::exception& e)
54924956598SShawn McCarney {
55024956598SShawn McCarney EXPECT_STREQ(e.what(),
55124956598SShawn McCarney "Unable to read STATUS_VOUT value for rail VDD2: "
55224956598SShawn McCarney "No PAGE number defined for rail VDD2");
55324956598SShawn McCarney }
55424956598SShawn McCarney }
55524956598SShawn McCarney
55624956598SShawn McCarney // Test where value read successfully
55724956598SShawn McCarney {
55824956598SShawn McCarney std::optional<uint8_t> page{2};
55924956598SShawn McCarney Rail rail{name,
56024956598SShawn McCarney presence,
56124956598SShawn McCarney page,
56224956598SShawn McCarney isPowerSupplyRail,
56324956598SShawn McCarney checkStatusVout,
56424956598SShawn McCarney compareVoltageToLimit,
56524956598SShawn McCarney gpio};
56624956598SShawn McCarney
56724956598SShawn McCarney MockDevice device{};
56824956598SShawn McCarney EXPECT_CALL(device, getStatusVout(2)).Times(1).WillOnce(Return(0xad));
56924956598SShawn McCarney
57024956598SShawn McCarney EXPECT_EQ(rail.getStatusVout(device), 0xad);
57124956598SShawn McCarney }
57224956598SShawn McCarney
57324956598SShawn McCarney // Test where exception occurs trying to read value
57424956598SShawn McCarney {
57524956598SShawn McCarney std::optional<uint8_t> page{2};
57624956598SShawn McCarney Rail rail{name,
57724956598SShawn McCarney presence,
57824956598SShawn McCarney page,
57924956598SShawn McCarney isPowerSupplyRail,
58024956598SShawn McCarney checkStatusVout,
58124956598SShawn McCarney compareVoltageToLimit,
58224956598SShawn McCarney gpio};
58324956598SShawn McCarney
58424956598SShawn McCarney MockDevice device{};
58524956598SShawn McCarney EXPECT_CALL(device, getStatusVout(2))
58624956598SShawn McCarney .Times(1)
58724956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
58824956598SShawn McCarney
58924956598SShawn McCarney try
59024956598SShawn McCarney {
59124956598SShawn McCarney rail.getStatusVout(device);
59224956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
59324956598SShawn McCarney }
59424956598SShawn McCarney catch (const std::exception& e)
59524956598SShawn McCarney {
59624956598SShawn McCarney EXPECT_STREQ(e.what(),
59724956598SShawn McCarney "Unable to read STATUS_VOUT value for rail VDD2: "
59824956598SShawn McCarney "File does not exist");
59924956598SShawn McCarney }
60024956598SShawn McCarney }
60124956598SShawn McCarney }
60224956598SShawn McCarney
TEST(RailTests,GetReadVout)60324956598SShawn McCarney TEST(RailTests, GetReadVout)
60424956598SShawn McCarney {
60524956598SShawn McCarney std::string name{"VDD2"};
60624956598SShawn McCarney std::optional<std::string> presence{};
60724956598SShawn McCarney bool isPowerSupplyRail{false};
60824956598SShawn McCarney bool checkStatusVout{false};
60924956598SShawn McCarney bool compareVoltageToLimit{false};
61024956598SShawn McCarney std::optional<GPIO> gpio{};
61124956598SShawn McCarney
61224956598SShawn McCarney // Test where page was not specified: Throws exception
61324956598SShawn McCarney {
61424956598SShawn McCarney std::optional<uint8_t> page{};
61524956598SShawn McCarney Rail rail{name,
61624956598SShawn McCarney presence,
61724956598SShawn McCarney page,
61824956598SShawn McCarney isPowerSupplyRail,
61924956598SShawn McCarney checkStatusVout,
62024956598SShawn McCarney compareVoltageToLimit,
62124956598SShawn McCarney gpio};
62224956598SShawn McCarney
62324956598SShawn McCarney MockDevice device{};
62424956598SShawn McCarney EXPECT_CALL(device, getReadVout).Times(0);
62524956598SShawn McCarney
62624956598SShawn McCarney try
62724956598SShawn McCarney {
62824956598SShawn McCarney rail.getReadVout(device);
62924956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
63024956598SShawn McCarney }
63124956598SShawn McCarney catch (const std::exception& e)
63224956598SShawn McCarney {
63324956598SShawn McCarney EXPECT_STREQ(e.what(),
63424956598SShawn McCarney "Unable to read READ_VOUT value for rail VDD2: "
63524956598SShawn McCarney "No PAGE number defined for rail VDD2");
63624956598SShawn McCarney }
63724956598SShawn McCarney }
63824956598SShawn McCarney
63924956598SShawn McCarney // Test where value read successfully
64024956598SShawn McCarney {
64124956598SShawn McCarney std::optional<uint8_t> page{2};
64224956598SShawn McCarney Rail rail{name,
64324956598SShawn McCarney presence,
64424956598SShawn McCarney page,
64524956598SShawn McCarney isPowerSupplyRail,
64624956598SShawn McCarney checkStatusVout,
64724956598SShawn McCarney compareVoltageToLimit,
64824956598SShawn McCarney gpio};
64924956598SShawn McCarney
65024956598SShawn McCarney MockDevice device{};
65124956598SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.23));
65224956598SShawn McCarney
65324956598SShawn McCarney EXPECT_EQ(rail.getReadVout(device), 1.23);
65424956598SShawn McCarney }
65524956598SShawn McCarney
65624956598SShawn McCarney // Test where exception occurs trying to read value
65724956598SShawn McCarney {
65824956598SShawn McCarney std::optional<uint8_t> page{2};
65924956598SShawn McCarney Rail rail{name,
66024956598SShawn McCarney presence,
66124956598SShawn McCarney page,
66224956598SShawn McCarney isPowerSupplyRail,
66324956598SShawn McCarney checkStatusVout,
66424956598SShawn McCarney compareVoltageToLimit,
66524956598SShawn McCarney gpio};
66624956598SShawn McCarney
66724956598SShawn McCarney MockDevice device{};
66824956598SShawn McCarney EXPECT_CALL(device, getReadVout(2))
66924956598SShawn McCarney .Times(1)
67024956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
67124956598SShawn McCarney
67224956598SShawn McCarney try
67324956598SShawn McCarney {
67424956598SShawn McCarney rail.getReadVout(device);
67524956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
67624956598SShawn McCarney }
67724956598SShawn McCarney catch (const std::exception& e)
67824956598SShawn McCarney {
67924956598SShawn McCarney EXPECT_STREQ(e.what(),
68024956598SShawn McCarney "Unable to read READ_VOUT value for rail VDD2: "
68124956598SShawn McCarney "File does not exist");
68224956598SShawn McCarney }
68324956598SShawn McCarney }
68424956598SShawn McCarney }
68524956598SShawn McCarney
TEST(RailTests,GetVoutUVFaultLimit)68624956598SShawn McCarney TEST(RailTests, GetVoutUVFaultLimit)
68724956598SShawn McCarney {
68824956598SShawn McCarney std::string name{"VDD2"};
68924956598SShawn McCarney std::optional<std::string> presence{};
69024956598SShawn McCarney bool isPowerSupplyRail{false};
69124956598SShawn McCarney bool checkStatusVout{false};
69224956598SShawn McCarney bool compareVoltageToLimit{false};
69324956598SShawn McCarney std::optional<GPIO> gpio{};
69424956598SShawn McCarney
69524956598SShawn McCarney // Test where page was not specified: Throws exception
69624956598SShawn McCarney {
69724956598SShawn McCarney std::optional<uint8_t> page{};
69824956598SShawn McCarney Rail rail{name,
69924956598SShawn McCarney presence,
70024956598SShawn McCarney page,
70124956598SShawn McCarney isPowerSupplyRail,
70224956598SShawn McCarney checkStatusVout,
70324956598SShawn McCarney compareVoltageToLimit,
70424956598SShawn McCarney gpio};
70524956598SShawn McCarney
70624956598SShawn McCarney MockDevice device{};
70724956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit).Times(0);
70824956598SShawn McCarney
70924956598SShawn McCarney try
71024956598SShawn McCarney {
71124956598SShawn McCarney rail.getVoutUVFaultLimit(device);
71224956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
71324956598SShawn McCarney }
71424956598SShawn McCarney catch (const std::exception& e)
71524956598SShawn McCarney {
71624956598SShawn McCarney EXPECT_STREQ(
71724956598SShawn McCarney e.what(),
71824956598SShawn McCarney "Unable to read VOUT_UV_FAULT_LIMIT value for rail VDD2: "
71924956598SShawn McCarney "No PAGE number defined for rail VDD2");
72024956598SShawn McCarney }
72124956598SShawn McCarney }
72224956598SShawn McCarney
72324956598SShawn McCarney // Test where value read successfully
72424956598SShawn McCarney {
72524956598SShawn McCarney std::optional<uint8_t> page{2};
72624956598SShawn McCarney Rail rail{name,
72724956598SShawn McCarney presence,
72824956598SShawn McCarney page,
72924956598SShawn McCarney isPowerSupplyRail,
73024956598SShawn McCarney checkStatusVout,
73124956598SShawn McCarney compareVoltageToLimit,
73224956598SShawn McCarney gpio};
73324956598SShawn McCarney
73424956598SShawn McCarney MockDevice device{};
73524956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
73624956598SShawn McCarney .Times(1)
73724956598SShawn McCarney .WillOnce(Return(0.9));
73824956598SShawn McCarney
73924956598SShawn McCarney EXPECT_EQ(rail.getVoutUVFaultLimit(device), 0.9);
74024956598SShawn McCarney }
74124956598SShawn McCarney
74224956598SShawn McCarney // Test where exception occurs trying to read value
74324956598SShawn McCarney {
74424956598SShawn McCarney std::optional<uint8_t> page{2};
74524956598SShawn McCarney Rail rail{name,
74624956598SShawn McCarney presence,
74724956598SShawn McCarney page,
74824956598SShawn McCarney isPowerSupplyRail,
74924956598SShawn McCarney checkStatusVout,
75024956598SShawn McCarney compareVoltageToLimit,
75124956598SShawn McCarney gpio};
75224956598SShawn McCarney
75324956598SShawn McCarney MockDevice device{};
75424956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
75524956598SShawn McCarney .Times(1)
75624956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
75724956598SShawn McCarney
75824956598SShawn McCarney try
75924956598SShawn McCarney {
76024956598SShawn McCarney rail.getVoutUVFaultLimit(device);
76124956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
76224956598SShawn McCarney }
76324956598SShawn McCarney catch (const std::exception& e)
76424956598SShawn McCarney {
76524956598SShawn McCarney EXPECT_STREQ(
76624956598SShawn McCarney e.what(),
76724956598SShawn McCarney "Unable to read VOUT_UV_FAULT_LIMIT value for rail VDD2: "
76824956598SShawn McCarney "File does not exist");
76924956598SShawn McCarney }
77024956598SShawn McCarney }
77124956598SShawn McCarney }
77224956598SShawn McCarney
TEST(RailTests,HasPgoodFault)77324956598SShawn McCarney TEST(RailTests, HasPgoodFault)
77424956598SShawn McCarney {
77524956598SShawn McCarney std::string name{"VDD2"};
776*16275831SShawn McCarney std::optional<std::string> presence{};
777*16275831SShawn McCarney std::optional<uint8_t> page{2};
77824956598SShawn McCarney bool isPowerSupplyRail{false};
779*16275831SShawn McCarney bool checkStatusVout{true};
780*16275831SShawn McCarney bool compareVoltageToLimit{true};
781*16275831SShawn McCarney bool activeLow{true};
782*16275831SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
783*16275831SShawn McCarney Rail rail{name,
784*16275831SShawn McCarney presence,
785*16275831SShawn McCarney page,
786*16275831SShawn McCarney isPowerSupplyRail,
787*16275831SShawn McCarney checkStatusVout,
788*16275831SShawn McCarney compareVoltageToLimit,
789*16275831SShawn McCarney gpio};
790*16275831SShawn McCarney
791*16275831SShawn McCarney // No fault detected
792*16275831SShawn McCarney {
793*16275831SShawn McCarney MockDevice device{};
794*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(2)).Times(1).WillOnce(Return(0x00));
795*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
796*16275831SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
797*16275831SShawn McCarney .Times(1)
798*16275831SShawn McCarney .WillOnce(Return(1.0));
799*16275831SShawn McCarney
800*16275831SShawn McCarney MockServices services{};
801*16275831SShawn McCarney
802*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 0, 0, 0};
803*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
804*16275831SShawn McCarney EXPECT_FALSE(
805*16275831SShawn McCarney rail.hasPgoodFault(device, services, gpioValues, additionalData));
806*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
807*16275831SShawn McCarney }
808*16275831SShawn McCarney
809*16275831SShawn McCarney // Fault detected via STATUS_VOUT
810*16275831SShawn McCarney {
811*16275831SShawn McCarney MockDevice device{};
812*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(2)).Times(1).WillOnce(Return(0x10));
813*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(0);
814*16275831SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
815*16275831SShawn McCarney
816*16275831SShawn McCarney MockServices services{};
817*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
818*16275831SShawn McCarney .Times(1);
819*16275831SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
820*16275831SShawn McCarney .Times(1);
821*16275831SShawn McCarney EXPECT_CALL(
822*16275831SShawn McCarney services,
823*16275831SShawn McCarney logErrorMsg("Rail VDD2 has fault bits set in STATUS_VOUT: 0x10"))
824*16275831SShawn McCarney .Times(1);
825*16275831SShawn McCarney
826*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 0, 0, 0};
827*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
828*16275831SShawn McCarney EXPECT_TRUE(
829*16275831SShawn McCarney rail.hasPgoodFault(device, services, gpioValues, additionalData));
830*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 3);
831*16275831SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
832*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_VOUT"], "0x10");
833*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
834*16275831SShawn McCarney }
835*16275831SShawn McCarney
836*16275831SShawn McCarney // Fault detected via GPIO
837*16275831SShawn McCarney {
838*16275831SShawn McCarney MockDevice device{};
839*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(2)).Times(1).WillOnce(Return(0x00));
840*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(0);
841*16275831SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
842*16275831SShawn McCarney
843*16275831SShawn McCarney MockServices services{};
844*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
845*16275831SShawn McCarney .Times(1);
846*16275831SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
847*16275831SShawn McCarney .Times(1);
848*16275831SShawn McCarney EXPECT_CALL(
849*16275831SShawn McCarney services,
850*16275831SShawn McCarney logErrorMsg(
851*16275831SShawn McCarney "Rail VDD2 pgood GPIO line offset 3 has inactive value 1"))
852*16275831SShawn McCarney .Times(1);
853*16275831SShawn McCarney
854*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 1, 0, 0};
855*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
856*16275831SShawn McCarney EXPECT_TRUE(
857*16275831SShawn McCarney rail.hasPgoodFault(device, services, gpioValues, additionalData));
858*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 4);
859*16275831SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
860*16275831SShawn McCarney EXPECT_EQ(additionalData["GPIO_LINE"], "3");
861*16275831SShawn McCarney EXPECT_EQ(additionalData["GPIO_VALUE"], "1");
862*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
863*16275831SShawn McCarney }
864*16275831SShawn McCarney
865*16275831SShawn McCarney // Fault detected via output voltage
866*16275831SShawn McCarney {
867*16275831SShawn McCarney MockDevice device{};
868*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(2)).Times(1).WillOnce(Return(0x00));
869*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
870*16275831SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
871*16275831SShawn McCarney .Times(1)
872*16275831SShawn McCarney .WillOnce(Return(1.1));
873*16275831SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
874*16275831SShawn McCarney
875*16275831SShawn McCarney MockServices services{};
876*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
877*16275831SShawn McCarney .Times(1);
878*16275831SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
879*16275831SShawn McCarney .Times(1);
880*16275831SShawn McCarney EXPECT_CALL(
881*16275831SShawn McCarney services,
882*16275831SShawn McCarney logErrorMsg(
883*16275831SShawn McCarney "Rail VDD2 output voltage 1.1V is <= UV fault limit 1.1V"))
884*16275831SShawn McCarney .Times(1);
885*16275831SShawn McCarney
886*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 0, 0, 0};
887*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
888*16275831SShawn McCarney EXPECT_TRUE(
889*16275831SShawn McCarney rail.hasPgoodFault(device, services, gpioValues, additionalData));
890*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 4);
891*16275831SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
892*16275831SShawn McCarney EXPECT_EQ(additionalData["READ_VOUT"], "1.1");
893*16275831SShawn McCarney EXPECT_EQ(additionalData["VOUT_UV_FAULT_LIMIT"], "1.1");
894*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
895*16275831SShawn McCarney }
896*16275831SShawn McCarney }
897*16275831SShawn McCarney
TEST(RailTests,HasPgoodFaultStatusVout)898*16275831SShawn McCarney TEST(RailTests, HasPgoodFaultStatusVout)
899*16275831SShawn McCarney {
900*16275831SShawn McCarney std::string name{"VDD2"};
901*16275831SShawn McCarney std::optional<uint8_t> page{3};
902*16275831SShawn McCarney bool isPowerSupplyRail{false};
903*16275831SShawn McCarney bool compareVoltageToLimit{false};
904*16275831SShawn McCarney std::optional<GPIO> gpio{};
905*16275831SShawn McCarney
906*16275831SShawn McCarney // Test where presence check defined: Rail is not present
907*16275831SShawn McCarney {
908*16275831SShawn McCarney std::optional<std::string> presence{
909*16275831SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
910*16275831SShawn McCarney bool checkStatusVout{true};
911*16275831SShawn McCarney Rail rail{name,
912*16275831SShawn McCarney presence,
913*16275831SShawn McCarney page,
914*16275831SShawn McCarney isPowerSupplyRail,
915*16275831SShawn McCarney checkStatusVout,
916*16275831SShawn McCarney compareVoltageToLimit,
917*16275831SShawn McCarney gpio};
918*16275831SShawn McCarney
919*16275831SShawn McCarney MockDevice device{};
920*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(0);
921*16275831SShawn McCarney
922*16275831SShawn McCarney MockServices services{};
923*16275831SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
924*16275831SShawn McCarney .Times(1)
925*16275831SShawn McCarney .WillOnce(Return(false));
926*16275831SShawn McCarney
927*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
928*16275831SShawn McCarney EXPECT_FALSE(
929*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
930*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
931*16275831SShawn McCarney }
932*16275831SShawn McCarney
933*16275831SShawn McCarney // Test where presence check defined: Rail is present: No fault detected
934*16275831SShawn McCarney {
935*16275831SShawn McCarney std::optional<std::string> presence{
936*16275831SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
937*16275831SShawn McCarney bool checkStatusVout{true};
938*16275831SShawn McCarney Rail rail{name,
939*16275831SShawn McCarney presence,
940*16275831SShawn McCarney page,
941*16275831SShawn McCarney isPowerSupplyRail,
942*16275831SShawn McCarney checkStatusVout,
943*16275831SShawn McCarney compareVoltageToLimit,
944*16275831SShawn McCarney gpio};
945*16275831SShawn McCarney
946*16275831SShawn McCarney MockDevice device{};
947*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x00));
948*16275831SShawn McCarney
949*16275831SShawn McCarney MockServices services{};
950*16275831SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
951*16275831SShawn McCarney .Times(1)
952*16275831SShawn McCarney .WillOnce(Return(true));
953*16275831SShawn McCarney
954*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
955*16275831SShawn McCarney EXPECT_FALSE(
956*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
957*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
958*16275831SShawn McCarney }
959*16275831SShawn McCarney
960*16275831SShawn McCarney // Test where STATUS_VOUT check is not defined
961*16275831SShawn McCarney {
962*16275831SShawn McCarney std::optional<std::string> presence{};
963*16275831SShawn McCarney bool checkStatusVout{false};
964*16275831SShawn McCarney Rail rail{name,
965*16275831SShawn McCarney presence,
966*16275831SShawn McCarney page,
967*16275831SShawn McCarney isPowerSupplyRail,
968*16275831SShawn McCarney checkStatusVout,
969*16275831SShawn McCarney compareVoltageToLimit,
970*16275831SShawn McCarney gpio};
971*16275831SShawn McCarney
972*16275831SShawn McCarney MockDevice device{};
973*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(0);
974*16275831SShawn McCarney
975*16275831SShawn McCarney MockServices services{};
976*16275831SShawn McCarney
977*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
978*16275831SShawn McCarney EXPECT_FALSE(
979*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
980*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
981*16275831SShawn McCarney }
982*16275831SShawn McCarney
983*16275831SShawn McCarney // Test where no fault detected: No warning bits set
984*16275831SShawn McCarney {
985*16275831SShawn McCarney std::optional<std::string> presence{};
986*16275831SShawn McCarney bool checkStatusVout{true};
987*16275831SShawn McCarney Rail rail{name,
988*16275831SShawn McCarney presence,
989*16275831SShawn McCarney page,
990*16275831SShawn McCarney isPowerSupplyRail,
991*16275831SShawn McCarney checkStatusVout,
992*16275831SShawn McCarney compareVoltageToLimit,
993*16275831SShawn McCarney gpio};
994*16275831SShawn McCarney
995*16275831SShawn McCarney MockDevice device{};
996*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x00));
997*16275831SShawn McCarney
998*16275831SShawn McCarney MockServices services{};
999*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg).Times(0);
1000*16275831SShawn McCarney
1001*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1002*16275831SShawn McCarney EXPECT_FALSE(
1003*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
1004*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
1005*16275831SShawn McCarney }
1006*16275831SShawn McCarney
1007*16275831SShawn McCarney // Test where no fault detected: Warning bits set
1008*16275831SShawn McCarney {
1009*16275831SShawn McCarney std::optional<std::string> presence{};
1010*16275831SShawn McCarney bool checkStatusVout{true};
1011*16275831SShawn McCarney Rail rail{name,
1012*16275831SShawn McCarney presence,
1013*16275831SShawn McCarney page,
1014*16275831SShawn McCarney isPowerSupplyRail,
1015*16275831SShawn McCarney checkStatusVout,
1016*16275831SShawn McCarney compareVoltageToLimit,
1017*16275831SShawn McCarney gpio};
1018*16275831SShawn McCarney
1019*16275831SShawn McCarney MockDevice device{};
1020*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x6a));
1021*16275831SShawn McCarney
1022*16275831SShawn McCarney MockServices services{};
1023*16275831SShawn McCarney EXPECT_CALL(
1024*16275831SShawn McCarney services,
1025*16275831SShawn McCarney logInfoMsg("Rail VDD2 has warning bits set in STATUS_VOUT: 0x6a"))
1026*16275831SShawn McCarney .Times(1);
1027*16275831SShawn McCarney
1028*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1029*16275831SShawn McCarney EXPECT_FALSE(
1030*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
1031*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
1032*16275831SShawn McCarney }
1033*16275831SShawn McCarney
1034*16275831SShawn McCarney // Test where fault detected
1035*16275831SShawn McCarney // STATUS_WORD captured in additional data
1036*16275831SShawn McCarney {
1037*16275831SShawn McCarney std::optional<std::string> presence{};
1038*16275831SShawn McCarney bool checkStatusVout{true};
1039*16275831SShawn McCarney Rail rail{name,
1040*16275831SShawn McCarney presence,
1041*16275831SShawn McCarney page,
1042*16275831SShawn McCarney isPowerSupplyRail,
1043*16275831SShawn McCarney checkStatusVout,
1044*16275831SShawn McCarney compareVoltageToLimit,
1045*16275831SShawn McCarney gpio};
1046*16275831SShawn McCarney
1047*16275831SShawn McCarney MockDevice device{};
1048*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3)).Times(1).WillOnce(Return(0x10));
1049*16275831SShawn McCarney EXPECT_CALL(device, getStatusWord(3)).Times(1).WillOnce(Return(0xbeef));
1050*16275831SShawn McCarney
1051*16275831SShawn McCarney MockServices services{};
1052*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
1053*16275831SShawn McCarney .Times(1);
1054*16275831SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
1055*16275831SShawn McCarney .Times(1);
1056*16275831SShawn McCarney EXPECT_CALL(
1057*16275831SShawn McCarney services,
1058*16275831SShawn McCarney logErrorMsg("Rail VDD2 has fault bits set in STATUS_VOUT: 0x10"))
1059*16275831SShawn McCarney .Times(1);
1060*16275831SShawn McCarney
1061*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1062*16275831SShawn McCarney EXPECT_TRUE(
1063*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData));
1064*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 3);
1065*16275831SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
1066*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_VOUT"], "0x10");
1067*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
1068*16275831SShawn McCarney }
1069*16275831SShawn McCarney
1070*16275831SShawn McCarney // Test where exception thrown
1071*16275831SShawn McCarney {
1072*16275831SShawn McCarney std::optional<std::string> presence{};
1073*16275831SShawn McCarney bool checkStatusVout{true};
1074*16275831SShawn McCarney Rail rail{name,
1075*16275831SShawn McCarney presence,
1076*16275831SShawn McCarney page,
1077*16275831SShawn McCarney isPowerSupplyRail,
1078*16275831SShawn McCarney checkStatusVout,
1079*16275831SShawn McCarney compareVoltageToLimit,
1080*16275831SShawn McCarney gpio};
1081*16275831SShawn McCarney
1082*16275831SShawn McCarney MockDevice device{};
1083*16275831SShawn McCarney EXPECT_CALL(device, getStatusVout(3))
1084*16275831SShawn McCarney .Times(1)
1085*16275831SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
1086*16275831SShawn McCarney
1087*16275831SShawn McCarney MockServices services{};
1088*16275831SShawn McCarney
1089*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1090*16275831SShawn McCarney try
1091*16275831SShawn McCarney {
1092*16275831SShawn McCarney rail.hasPgoodFaultStatusVout(device, services, additionalData);
1093*16275831SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
1094*16275831SShawn McCarney }
1095*16275831SShawn McCarney catch (const std::exception& e)
1096*16275831SShawn McCarney {
1097*16275831SShawn McCarney EXPECT_STREQ(e.what(),
1098*16275831SShawn McCarney "Unable to read STATUS_VOUT value for rail VDD2: "
1099*16275831SShawn McCarney "File does not exist");
1100*16275831SShawn McCarney }
1101*16275831SShawn McCarney }
1102*16275831SShawn McCarney }
1103*16275831SShawn McCarney
TEST(RailTests,HasPgoodFaultGPIO)1104*16275831SShawn McCarney TEST(RailTests, HasPgoodFaultGPIO)
1105*16275831SShawn McCarney {
1106*16275831SShawn McCarney std::string name{"VDD2"};
1107*16275831SShawn McCarney bool isPowerSupplyRail{false};
1108*16275831SShawn McCarney bool checkStatusVout{false};
1109*16275831SShawn McCarney bool compareVoltageToLimit{false};
111024956598SShawn McCarney
111124956598SShawn McCarney // Test where presence check defined: Rail is not present
111224956598SShawn McCarney {
111324956598SShawn McCarney std::optional<std::string> presence{
111424956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
111524956598SShawn McCarney std::optional<uint8_t> page{3};
1116*16275831SShawn McCarney bool activeLow{false};
1117*16275831SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
111824956598SShawn McCarney Rail rail{name,
111924956598SShawn McCarney presence,
112024956598SShawn McCarney page,
112124956598SShawn McCarney isPowerSupplyRail,
112224956598SShawn McCarney checkStatusVout,
112324956598SShawn McCarney compareVoltageToLimit,
112424956598SShawn McCarney gpio};
112524956598SShawn McCarney
112624956598SShawn McCarney MockDevice device{};
112724956598SShawn McCarney
112824956598SShawn McCarney MockServices services{};
112924956598SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
113024956598SShawn McCarney .Times(1)
113124956598SShawn McCarney .WillOnce(Return(false));
113224956598SShawn McCarney
1133*16275831SShawn McCarney std::vector<int> gpioValues{1, 1, 1, 0, 1, 1};
113424956598SShawn McCarney std::map<std::string, std::string> additionalData{};
1135*16275831SShawn McCarney EXPECT_FALSE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1136*16275831SShawn McCarney additionalData));
113724956598SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
113824956598SShawn McCarney }
113924956598SShawn McCarney
1140*16275831SShawn McCarney // Test where presence check defined: Rail is present: No fault detected
114124956598SShawn McCarney {
114224956598SShawn McCarney std::optional<std::string> presence{
114324956598SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
1144*16275831SShawn McCarney std::optional<uint8_t> page{3};
1145*16275831SShawn McCarney bool activeLow{false};
1146*16275831SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
114724956598SShawn McCarney Rail rail{name,
114824956598SShawn McCarney presence,
114924956598SShawn McCarney page,
115024956598SShawn McCarney isPowerSupplyRail,
115124956598SShawn McCarney checkStatusVout,
115224956598SShawn McCarney compareVoltageToLimit,
115324956598SShawn McCarney gpio};
115424956598SShawn McCarney
115524956598SShawn McCarney MockDevice device{};
115624956598SShawn McCarney
115724956598SShawn McCarney MockServices services{};
115824956598SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
115924956598SShawn McCarney .Times(1)
116024956598SShawn McCarney .WillOnce(Return(true));
116124956598SShawn McCarney
1162*16275831SShawn McCarney std::vector<int> gpioValues{1, 1, 1, 1, 1, 1};
116324956598SShawn McCarney std::map<std::string, std::string> additionalData{};
1164*16275831SShawn McCarney EXPECT_FALSE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1165*16275831SShawn McCarney additionalData));
116624956598SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
116724956598SShawn McCarney }
116824956598SShawn McCarney
1169*16275831SShawn McCarney // Test where GPIO check not defined
117024956598SShawn McCarney {
117124956598SShawn McCarney std::optional<std::string> presence{};
1172*16275831SShawn McCarney std::optional<uint8_t> page{3};
117324956598SShawn McCarney std::optional<GPIO> gpio{};
117424956598SShawn McCarney Rail rail{name,
117524956598SShawn McCarney presence,
117624956598SShawn McCarney page,
117724956598SShawn McCarney isPowerSupplyRail,
117824956598SShawn McCarney checkStatusVout,
117924956598SShawn McCarney compareVoltageToLimit,
118024956598SShawn McCarney gpio};
118124956598SShawn McCarney
118224956598SShawn McCarney MockDevice device{};
118324956598SShawn McCarney
118424956598SShawn McCarney MockServices services{};
118524956598SShawn McCarney
1186*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 0, 0, 0};
118724956598SShawn McCarney std::map<std::string, std::string> additionalData{};
1188*16275831SShawn McCarney EXPECT_FALSE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1189*16275831SShawn McCarney additionalData));
119024956598SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
119124956598SShawn McCarney }
119224956598SShawn McCarney
1193*16275831SShawn McCarney // Test where no fault detected
119424956598SShawn McCarney // GPIO value is 1 and GPIO is active high
119524956598SShawn McCarney {
119624956598SShawn McCarney std::optional<std::string> presence{};
119724956598SShawn McCarney std::optional<uint8_t> page{};
119824956598SShawn McCarney bool activeLow{false};
119924956598SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
120024956598SShawn McCarney Rail rail{name,
120124956598SShawn McCarney presence,
120224956598SShawn McCarney page,
120324956598SShawn McCarney isPowerSupplyRail,
120424956598SShawn McCarney checkStatusVout,
120524956598SShawn McCarney compareVoltageToLimit,
120624956598SShawn McCarney gpio};
120724956598SShawn McCarney
120824956598SShawn McCarney MockDevice device{};
120924956598SShawn McCarney
121024956598SShawn McCarney MockServices services{};
121124956598SShawn McCarney
121224956598SShawn McCarney std::vector<int> gpioValues{1, 1, 1, 1, 1, 1};
121324956598SShawn McCarney std::map<std::string, std::string> additionalData{};
1214*16275831SShawn McCarney EXPECT_FALSE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1215*16275831SShawn McCarney additionalData));
121624956598SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
121724956598SShawn McCarney }
121824956598SShawn McCarney
1219*16275831SShawn McCarney // Test where fault detected
122024956598SShawn McCarney // GPIO value is 0 and GPIO is active high
122124956598SShawn McCarney // STATUS_WORD not captured since no PMBus page defined
122224956598SShawn McCarney {
122324956598SShawn McCarney std::optional<std::string> presence{};
122424956598SShawn McCarney std::optional<uint8_t> page{};
122524956598SShawn McCarney bool activeLow{false};
122624956598SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
122724956598SShawn McCarney Rail rail{name,
122824956598SShawn McCarney presence,
122924956598SShawn McCarney page,
123024956598SShawn McCarney isPowerSupplyRail,
123124956598SShawn McCarney checkStatusVout,
123224956598SShawn McCarney compareVoltageToLimit,
123324956598SShawn McCarney gpio};
123424956598SShawn McCarney
123524956598SShawn McCarney MockDevice device{};
123624956598SShawn McCarney
123724956598SShawn McCarney MockServices services{};
123824956598SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
123924956598SShawn McCarney .Times(1);
124024956598SShawn McCarney EXPECT_CALL(
124124956598SShawn McCarney services,
124224956598SShawn McCarney logErrorMsg(
124324956598SShawn McCarney "Rail VDD2 pgood GPIO line offset 3 has inactive value 0"))
124424956598SShawn McCarney .Times(1);
124524956598SShawn McCarney
124624956598SShawn McCarney std::vector<int> gpioValues{1, 1, 1, 0, 1, 1};
124724956598SShawn McCarney std::map<std::string, std::string> additionalData{};
1248*16275831SShawn McCarney EXPECT_TRUE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1249*16275831SShawn McCarney additionalData));
125024956598SShawn McCarney EXPECT_EQ(additionalData.size(), 3);
125124956598SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
125224956598SShawn McCarney EXPECT_EQ(additionalData["GPIO_LINE"], "3");
125324956598SShawn McCarney EXPECT_EQ(additionalData["GPIO_VALUE"], "0");
125424956598SShawn McCarney }
125524956598SShawn McCarney
1256*16275831SShawn McCarney // Test where fault detected
1257*16275831SShawn McCarney // GPIO value is 1 and GPIO is active low
1258*16275831SShawn McCarney {
1259*16275831SShawn McCarney std::optional<std::string> presence{};
1260*16275831SShawn McCarney std::optional<uint8_t> page{2};
1261*16275831SShawn McCarney bool activeLow{true};
1262*16275831SShawn McCarney std::optional<GPIO> gpio{GPIO(3, activeLow)};
1263*16275831SShawn McCarney Rail rail{name,
1264*16275831SShawn McCarney presence,
1265*16275831SShawn McCarney page,
1266*16275831SShawn McCarney isPowerSupplyRail,
1267*16275831SShawn McCarney checkStatusVout,
1268*16275831SShawn McCarney compareVoltageToLimit,
1269*16275831SShawn McCarney gpio};
1270*16275831SShawn McCarney
1271*16275831SShawn McCarney MockDevice device{};
1272*16275831SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
1273*16275831SShawn McCarney
1274*16275831SShawn McCarney MockServices services{};
1275*16275831SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
1276*16275831SShawn McCarney .Times(1);
1277*16275831SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
1278*16275831SShawn McCarney .Times(1);
1279*16275831SShawn McCarney EXPECT_CALL(
1280*16275831SShawn McCarney services,
1281*16275831SShawn McCarney logErrorMsg(
1282*16275831SShawn McCarney "Rail VDD2 pgood GPIO line offset 3 has inactive value 1"))
1283*16275831SShawn McCarney .Times(1);
1284*16275831SShawn McCarney
1285*16275831SShawn McCarney std::vector<int> gpioValues{0, 0, 0, 1, 0, 0};
1286*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1287*16275831SShawn McCarney EXPECT_TRUE(rail.hasPgoodFaultGPIO(device, services, gpioValues,
1288*16275831SShawn McCarney additionalData));
1289*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 4);
1290*16275831SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
1291*16275831SShawn McCarney EXPECT_EQ(additionalData["GPIO_LINE"], "3");
1292*16275831SShawn McCarney EXPECT_EQ(additionalData["GPIO_VALUE"], "1");
1293*16275831SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
1294*16275831SShawn McCarney }
1295*16275831SShawn McCarney
1296*16275831SShawn McCarney // Test where exception thrown
129724956598SShawn McCarney {
129824956598SShawn McCarney std::optional<std::string> presence{};
129924956598SShawn McCarney std::optional<uint8_t> page{};
130024956598SShawn McCarney bool activeLow{false};
130124956598SShawn McCarney std::optional<GPIO> gpio{GPIO(6, activeLow)};
130224956598SShawn McCarney Rail rail{name,
130324956598SShawn McCarney presence,
130424956598SShawn McCarney page,
130524956598SShawn McCarney isPowerSupplyRail,
130624956598SShawn McCarney checkStatusVout,
130724956598SShawn McCarney compareVoltageToLimit,
130824956598SShawn McCarney gpio};
130924956598SShawn McCarney
131024956598SShawn McCarney MockDevice device{};
131124956598SShawn McCarney
131224956598SShawn McCarney MockServices services{};
131324956598SShawn McCarney
131424956598SShawn McCarney std::vector<int> gpioValues{1, 1, 1, 1, 1, 1};
131524956598SShawn McCarney std::map<std::string, std::string> additionalData{};
131624956598SShawn McCarney try
131724956598SShawn McCarney {
1318*16275831SShawn McCarney rail.hasPgoodFaultGPIO(device, services, gpioValues,
1319*16275831SShawn McCarney additionalData);
132024956598SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
132124956598SShawn McCarney }
132224956598SShawn McCarney catch (const std::exception& e)
132324956598SShawn McCarney {
132424956598SShawn McCarney EXPECT_STREQ(e.what(), "Invalid GPIO line offset 6 for rail VDD2: "
132524956598SShawn McCarney "Device only has 6 GPIO values");
132624956598SShawn McCarney }
132724956598SShawn McCarney }
1328*16275831SShawn McCarney }
132924956598SShawn McCarney
TEST(RailTests,HasPgoodFaultOutputVoltage)1330*16275831SShawn McCarney TEST(RailTests, HasPgoodFaultOutputVoltage)
1331*16275831SShawn McCarney {
1332*16275831SShawn McCarney std::string name{"VDD2"};
1333*16275831SShawn McCarney std::optional<uint8_t> page{2};
1334*16275831SShawn McCarney bool isPowerSupplyRail{false};
1335*16275831SShawn McCarney bool checkStatusVout{false};
1336*16275831SShawn McCarney std::optional<GPIO> gpio{};
1337*16275831SShawn McCarney
1338*16275831SShawn McCarney // Test where presence check defined: Rail is not present
1339*16275831SShawn McCarney {
1340*16275831SShawn McCarney std::optional<std::string> presence{
1341*16275831SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
1342*16275831SShawn McCarney bool compareVoltageToLimit{true};
1343*16275831SShawn McCarney Rail rail{name,
1344*16275831SShawn McCarney presence,
1345*16275831SShawn McCarney page,
1346*16275831SShawn McCarney isPowerSupplyRail,
1347*16275831SShawn McCarney checkStatusVout,
1348*16275831SShawn McCarney compareVoltageToLimit,
1349*16275831SShawn McCarney gpio};
1350*16275831SShawn McCarney
1351*16275831SShawn McCarney MockDevice device{};
1352*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(0);
1353*16275831SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2)).Times(0);
1354*16275831SShawn McCarney
1355*16275831SShawn McCarney MockServices services{};
1356*16275831SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
1357*16275831SShawn McCarney .Times(1)
1358*16275831SShawn McCarney .WillOnce(Return(false));
1359*16275831SShawn McCarney
1360*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1361*16275831SShawn McCarney EXPECT_FALSE(
1362*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
1363*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
1364*16275831SShawn McCarney }
1365*16275831SShawn McCarney
1366*16275831SShawn McCarney // Test where presence check defined: Rail is present: No fault detected
1367*16275831SShawn McCarney {
1368*16275831SShawn McCarney std::optional<std::string> presence{
1369*16275831SShawn McCarney "/xyz/openbmc_project/inventory/system/chassis/motherboard/cpu2"};
1370*16275831SShawn McCarney bool compareVoltageToLimit{true};
1371*16275831SShawn McCarney Rail rail{name,
1372*16275831SShawn McCarney presence,
1373*16275831SShawn McCarney page,
1374*16275831SShawn McCarney isPowerSupplyRail,
1375*16275831SShawn McCarney checkStatusVout,
1376*16275831SShawn McCarney compareVoltageToLimit,
1377*16275831SShawn McCarney gpio};
1378*16275831SShawn McCarney
1379*16275831SShawn McCarney MockDevice device{};
1380*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
1381*16275831SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
1382*16275831SShawn McCarney .Times(1)
1383*16275831SShawn McCarney .WillOnce(Return(1.0));
1384*16275831SShawn McCarney
1385*16275831SShawn McCarney MockServices services{};
1386*16275831SShawn McCarney EXPECT_CALL(services, isPresent(*presence))
1387*16275831SShawn McCarney .Times(1)
1388*16275831SShawn McCarney .WillOnce(Return(true));
1389*16275831SShawn McCarney
1390*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1391*16275831SShawn McCarney EXPECT_FALSE(
1392*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
1393*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
1394*16275831SShawn McCarney }
1395*16275831SShawn McCarney
1396*16275831SShawn McCarney // Test where voltage output check not specified
139724956598SShawn McCarney {
139824956598SShawn McCarney std::optional<std::string> presence{};
1399*16275831SShawn McCarney bool compareVoltageToLimit{false};
1400*16275831SShawn McCarney Rail rail{name,
1401*16275831SShawn McCarney presence,
1402*16275831SShawn McCarney page,
1403*16275831SShawn McCarney isPowerSupplyRail,
1404*16275831SShawn McCarney checkStatusVout,
1405*16275831SShawn McCarney compareVoltageToLimit,
1406*16275831SShawn McCarney gpio};
1407*16275831SShawn McCarney
1408*16275831SShawn McCarney MockDevice device{};
1409*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(0);
1410*16275831SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2)).Times(0);
1411*16275831SShawn McCarney
1412*16275831SShawn McCarney MockServices services{};
1413*16275831SShawn McCarney
1414*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1415*16275831SShawn McCarney EXPECT_FALSE(
1416*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
1417*16275831SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
1418*16275831SShawn McCarney }
1419*16275831SShawn McCarney
1420*16275831SShawn McCarney // Test where no fault detected: Output voltage > UV limit
1421*16275831SShawn McCarney {
1422*16275831SShawn McCarney std::optional<std::string> presence{};
142324956598SShawn McCarney bool compareVoltageToLimit{true};
142424956598SShawn McCarney Rail rail{name,
142524956598SShawn McCarney presence,
142624956598SShawn McCarney page,
142724956598SShawn McCarney isPowerSupplyRail,
142824956598SShawn McCarney checkStatusVout,
142924956598SShawn McCarney compareVoltageToLimit,
143024956598SShawn McCarney gpio};
143124956598SShawn McCarney
143224956598SShawn McCarney MockDevice device{};
143324956598SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
143424956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
143524956598SShawn McCarney .Times(1)
143624956598SShawn McCarney .WillOnce(Return(1.0));
143724956598SShawn McCarney
143824956598SShawn McCarney MockServices services{};
143924956598SShawn McCarney
144024956598SShawn McCarney std::map<std::string, std::string> additionalData{};
144124956598SShawn McCarney EXPECT_FALSE(
1442*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
144324956598SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
144424956598SShawn McCarney }
144524956598SShawn McCarney
1446*16275831SShawn McCarney // Test where fault detected: Output voltage < UV limit
144724956598SShawn McCarney {
144824956598SShawn McCarney std::optional<std::string> presence{};
144924956598SShawn McCarney bool compareVoltageToLimit{true};
145024956598SShawn McCarney Rail rail{name,
145124956598SShawn McCarney presence,
145224956598SShawn McCarney page,
145324956598SShawn McCarney isPowerSupplyRail,
145424956598SShawn McCarney checkStatusVout,
145524956598SShawn McCarney compareVoltageToLimit,
145624956598SShawn McCarney gpio};
145724956598SShawn McCarney
145824956598SShawn McCarney MockDevice device{};
145924956598SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
146024956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
146124956598SShawn McCarney .Times(1)
146224956598SShawn McCarney .WillOnce(Return(1.2));
146324956598SShawn McCarney EXPECT_CALL(device, getStatusWord(2)).Times(1).WillOnce(Return(0xbeef));
146424956598SShawn McCarney
146524956598SShawn McCarney MockServices services{};
146624956598SShawn McCarney EXPECT_CALL(services, logInfoMsg("Rail VDD2 STATUS_WORD: 0xbeef"))
146724956598SShawn McCarney .Times(1);
146824956598SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
146924956598SShawn McCarney .Times(1);
147024956598SShawn McCarney EXPECT_CALL(
147124956598SShawn McCarney services,
147224956598SShawn McCarney logErrorMsg(
147324956598SShawn McCarney "Rail VDD2 output voltage 1.1V is <= UV fault limit 1.2V"))
147424956598SShawn McCarney .Times(1);
147524956598SShawn McCarney
147624956598SShawn McCarney std::map<std::string, std::string> additionalData{};
147724956598SShawn McCarney EXPECT_TRUE(
1478*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
147924956598SShawn McCarney EXPECT_EQ(additionalData.size(), 4);
148024956598SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
148124956598SShawn McCarney EXPECT_EQ(additionalData["READ_VOUT"], "1.1");
148224956598SShawn McCarney EXPECT_EQ(additionalData["VOUT_UV_FAULT_LIMIT"], "1.2");
148324956598SShawn McCarney EXPECT_EQ(additionalData["STATUS_WORD"], "0xbeef");
148424956598SShawn McCarney }
148524956598SShawn McCarney
1486*16275831SShawn McCarney // Test where fault detected: Output voltage == UV limit
148724956598SShawn McCarney // STATUS_WORD not captured because reading it caused an exception
148824956598SShawn McCarney {
148924956598SShawn McCarney std::optional<std::string> presence{};
149024956598SShawn McCarney bool compareVoltageToLimit{true};
149124956598SShawn McCarney Rail rail{name,
149224956598SShawn McCarney presence,
149324956598SShawn McCarney page,
149424956598SShawn McCarney isPowerSupplyRail,
149524956598SShawn McCarney checkStatusVout,
149624956598SShawn McCarney compareVoltageToLimit,
149724956598SShawn McCarney gpio};
149824956598SShawn McCarney
149924956598SShawn McCarney MockDevice device{};
150024956598SShawn McCarney EXPECT_CALL(device, getReadVout(2)).Times(1).WillOnce(Return(1.1));
150124956598SShawn McCarney EXPECT_CALL(device, getVoutUVFaultLimit(2))
150224956598SShawn McCarney .Times(1)
150324956598SShawn McCarney .WillOnce(Return(1.1));
150424956598SShawn McCarney EXPECT_CALL(device, getStatusWord(2))
150524956598SShawn McCarney .Times(1)
150624956598SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
150724956598SShawn McCarney
150824956598SShawn McCarney MockServices services{};
150924956598SShawn McCarney EXPECT_CALL(services, logErrorMsg("Pgood fault detected in rail VDD2"))
151024956598SShawn McCarney .Times(1);
151124956598SShawn McCarney EXPECT_CALL(
151224956598SShawn McCarney services,
151324956598SShawn McCarney logErrorMsg(
151424956598SShawn McCarney "Rail VDD2 output voltage 1.1V is <= UV fault limit 1.1V"))
151524956598SShawn McCarney .Times(1);
151624956598SShawn McCarney
151724956598SShawn McCarney std::map<std::string, std::string> additionalData{};
151824956598SShawn McCarney EXPECT_TRUE(
1519*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData));
152024956598SShawn McCarney EXPECT_EQ(additionalData.size(), 3);
152124956598SShawn McCarney EXPECT_EQ(additionalData["RAIL_NAME"], "VDD2");
152224956598SShawn McCarney EXPECT_EQ(additionalData["READ_VOUT"], "1.1");
152324956598SShawn McCarney EXPECT_EQ(additionalData["VOUT_UV_FAULT_LIMIT"], "1.1");
152424956598SShawn McCarney }
1525*16275831SShawn McCarney
1526*16275831SShawn McCarney // Test where exception thrown
1527*16275831SShawn McCarney {
1528*16275831SShawn McCarney std::optional<std::string> presence{};
1529*16275831SShawn McCarney bool compareVoltageToLimit{true};
1530*16275831SShawn McCarney Rail rail{name,
1531*16275831SShawn McCarney presence,
1532*16275831SShawn McCarney page,
1533*16275831SShawn McCarney isPowerSupplyRail,
1534*16275831SShawn McCarney checkStatusVout,
1535*16275831SShawn McCarney compareVoltageToLimit,
1536*16275831SShawn McCarney gpio};
1537*16275831SShawn McCarney
1538*16275831SShawn McCarney MockDevice device{};
1539*16275831SShawn McCarney EXPECT_CALL(device, getReadVout(2))
1540*16275831SShawn McCarney .Times(1)
1541*16275831SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
1542*16275831SShawn McCarney
1543*16275831SShawn McCarney MockServices services{};
1544*16275831SShawn McCarney
1545*16275831SShawn McCarney std::map<std::string, std::string> additionalData{};
1546*16275831SShawn McCarney try
1547*16275831SShawn McCarney {
1548*16275831SShawn McCarney rail.hasPgoodFaultOutputVoltage(device, services, additionalData);
1549*16275831SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
1550*16275831SShawn McCarney }
1551*16275831SShawn McCarney catch (const std::exception& e)
1552*16275831SShawn McCarney {
1553*16275831SShawn McCarney EXPECT_STREQ(e.what(),
1554*16275831SShawn McCarney "Unable to read READ_VOUT value for rail VDD2: "
1555*16275831SShawn McCarney "File does not exist");
1556*16275831SShawn McCarney }
1557*16275831SShawn McCarney }
155824956598SShawn McCarney }
1559