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