1b89395b1SShawn McCarney /**
2b89395b1SShawn McCarney * Copyright © 2024 IBM Corporation
3b89395b1SShawn McCarney *
4b89395b1SShawn McCarney * Licensed under the Apache License, Version 2.0 (the "License");
5b89395b1SShawn McCarney * you may not use this file except in compliance with the License.
6b89395b1SShawn McCarney * You may obtain a copy of the License at
7b89395b1SShawn McCarney *
8b89395b1SShawn McCarney * http://www.apache.org/licenses/LICENSE-2.0
9b89395b1SShawn McCarney *
10b89395b1SShawn McCarney * Unless required by applicable law or agreed to in writing, software
11b89395b1SShawn McCarney * distributed under the License is distributed on an "AS IS" BASIS,
12b89395b1SShawn McCarney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b89395b1SShawn McCarney * See the License for the specific language governing permissions and
14b89395b1SShawn McCarney * limitations under the License.
15b89395b1SShawn McCarney */
16b89395b1SShawn McCarney
17b89395b1SShawn McCarney #include "mock_pmbus.hpp"
18b89395b1SShawn McCarney #include "mock_services.hpp"
19b89395b1SShawn McCarney #include "pmbus.hpp"
20b89395b1SShawn McCarney #include "pmbus_driver_device.hpp"
21b89395b1SShawn McCarney #include "rail.hpp"
22b89395b1SShawn McCarney #include "services.hpp"
23e9144ab4SShawn McCarney #include "temporary_subdirectory.hpp"
24b89395b1SShawn McCarney
25b89395b1SShawn McCarney #include <cstdint>
26b89395b1SShawn McCarney #include <exception>
27b89395b1SShawn McCarney #include <filesystem>
28b89395b1SShawn McCarney #include <format>
29b89395b1SShawn McCarney #include <fstream>
30b89395b1SShawn McCarney #include <map>
31b89395b1SShawn McCarney #include <memory>
32b89395b1SShawn McCarney #include <optional>
33b89395b1SShawn McCarney #include <stdexcept>
34b89395b1SShawn McCarney #include <string>
35b89395b1SShawn McCarney #include <utility>
36b89395b1SShawn McCarney #include <vector>
37b89395b1SShawn McCarney
38b89395b1SShawn McCarney #include <gmock/gmock.h>
39b89395b1SShawn McCarney #include <gtest/gtest.h>
40b89395b1SShawn McCarney
41b89395b1SShawn McCarney using namespace phosphor::power::sequencer;
42b89395b1SShawn McCarney using namespace phosphor::pmbus;
43e9144ab4SShawn McCarney using namespace phosphor::power::util;
44e9144ab4SShawn McCarney namespace fs = std::filesystem;
45b89395b1SShawn McCarney
46b89395b1SShawn McCarney using ::testing::Return;
47b89395b1SShawn McCarney using ::testing::Throw;
48b89395b1SShawn McCarney
49b89395b1SShawn McCarney class PMBusDriverDeviceTests : public ::testing::Test
50b89395b1SShawn McCarney {
51b89395b1SShawn McCarney protected:
52b89395b1SShawn McCarney /**
53b89395b1SShawn McCarney * Constructor.
54b89395b1SShawn McCarney *
55b89395b1SShawn McCarney * Creates a temporary directory to use in simulating sysfs files.
56b89395b1SShawn McCarney */
PMBusDriverDeviceTests()57b89395b1SShawn McCarney PMBusDriverDeviceTests() : ::testing::Test{}
58b89395b1SShawn McCarney {
59e9144ab4SShawn McCarney tempDirPath = tempDir.getPath();
60b89395b1SShawn McCarney }
61b89395b1SShawn McCarney
62b89395b1SShawn McCarney /**
63b89395b1SShawn McCarney * Creates a Rail object that checks for a pgood fault using STATUS_VOUT.
64b89395b1SShawn McCarney *
65b89395b1SShawn McCarney * @param name Unique name for the rail
66b89395b1SShawn McCarney * @param pageNum PMBus PAGE number of the rail
67b89395b1SShawn McCarney * @return Rail object
68b89395b1SShawn McCarney */
createRail(const std::string & name,uint8_t pageNum)69b89395b1SShawn McCarney std::unique_ptr<Rail> createRail(const std::string& name, uint8_t pageNum)
70b89395b1SShawn McCarney {
71b89395b1SShawn McCarney std::optional<std::string> presence{};
72b89395b1SShawn McCarney std::optional<uint8_t> page{pageNum};
73b89395b1SShawn McCarney bool isPowerSupplyRail{false};
74b89395b1SShawn McCarney bool checkStatusVout{true};
75b89395b1SShawn McCarney bool compareVoltageToLimit{false};
76b89395b1SShawn McCarney std::optional<GPIO> gpio{};
77b89395b1SShawn McCarney return std::make_unique<Rail>(name, presence, page, isPowerSupplyRail,
78b89395b1SShawn McCarney checkStatusVout, compareVoltageToLimit,
79b89395b1SShawn McCarney gpio);
80b89395b1SShawn McCarney }
81b89395b1SShawn McCarney
82b89395b1SShawn McCarney /**
83b89395b1SShawn McCarney * Creates a file with the specified contents within the temporary
84b89395b1SShawn McCarney * directory.
85b89395b1SShawn McCarney *
86b89395b1SShawn McCarney * @param name File name
87b89395b1SShawn McCarney * @param contents File contents
88b89395b1SShawn McCarney */
createFile(const std::string & name,const std::string & contents="")89b89395b1SShawn McCarney void createFile(const std::string& name, const std::string& contents = "")
90b89395b1SShawn McCarney {
91e9144ab4SShawn McCarney fs::path path{tempDirPath / name};
92b89395b1SShawn McCarney std::ofstream out{path};
93b89395b1SShawn McCarney out << contents;
94b89395b1SShawn McCarney out.close();
95b89395b1SShawn McCarney }
96b89395b1SShawn McCarney
97b89395b1SShawn McCarney /**
98e9144ab4SShawn McCarney * Temporary subdirectory used to create simulated sysfs / hmmon files.
99b89395b1SShawn McCarney */
100e9144ab4SShawn McCarney TemporarySubDirectory tempDir;
101e9144ab4SShawn McCarney
102e9144ab4SShawn McCarney /**
103e9144ab4SShawn McCarney * Path to temporary subdirectory.
104e9144ab4SShawn McCarney */
105e9144ab4SShawn McCarney fs::path tempDirPath;
106b89395b1SShawn McCarney };
107b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,Constructor)108b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, Constructor)
109b89395b1SShawn McCarney {
110b89395b1SShawn McCarney // Test where works; optional parameters not specified
111b89395b1SShawn McCarney {
112b89395b1SShawn McCarney MockServices services;
113b89395b1SShawn McCarney
114b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
115b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
116b89395b1SShawn McCarney rails.emplace_back(createRail("VDD", 5));
117b89395b1SShawn McCarney rails.emplace_back(createRail("VIO", 7));
118b89395b1SShawn McCarney uint8_t bus{3};
119b89395b1SShawn McCarney uint16_t address{0x72};
120b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
121b89395b1SShawn McCarney address};
122b89395b1SShawn McCarney
123b89395b1SShawn McCarney EXPECT_EQ(device.getName(), name);
124b89395b1SShawn McCarney EXPECT_EQ(device.getRails().size(), 2);
125b89395b1SShawn McCarney EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
126b89395b1SShawn McCarney EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
127b89395b1SShawn McCarney EXPECT_EQ(device.getBus(), bus);
128b89395b1SShawn McCarney EXPECT_EQ(device.getAddress(), address);
129b89395b1SShawn McCarney EXPECT_EQ(device.getDriverName(), "");
130b89395b1SShawn McCarney EXPECT_EQ(device.getInstance(), 0);
131b89395b1SShawn McCarney EXPECT_NE(&(device.getPMBusInterface()), nullptr);
132b89395b1SShawn McCarney }
133b89395b1SShawn McCarney
134b89395b1SShawn McCarney // Test where works; optional parameters specified
135b89395b1SShawn McCarney {
136b89395b1SShawn McCarney MockServices services;
137b89395b1SShawn McCarney
138b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
139b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
140b89395b1SShawn McCarney rails.emplace_back(createRail("VDD", 5));
141b89395b1SShawn McCarney rails.emplace_back(createRail("VIO", 7));
142b89395b1SShawn McCarney uint8_t bus{3};
143b89395b1SShawn McCarney uint16_t address{0x72};
144b89395b1SShawn McCarney std::string driverName{"xyzdev"};
145b89395b1SShawn McCarney size_t instance{3};
146b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
147b89395b1SShawn McCarney address, driverName, instance};
148b89395b1SShawn McCarney
149b89395b1SShawn McCarney EXPECT_EQ(device.getName(), name);
150b89395b1SShawn McCarney EXPECT_EQ(device.getRails().size(), 2);
151b89395b1SShawn McCarney EXPECT_EQ(device.getRails()[0]->getName(), "VDD");
152b89395b1SShawn McCarney EXPECT_EQ(device.getRails()[1]->getName(), "VIO");
153b89395b1SShawn McCarney EXPECT_EQ(device.getBus(), bus);
154b89395b1SShawn McCarney EXPECT_EQ(device.getAddress(), address);
155b89395b1SShawn McCarney EXPECT_EQ(device.getDriverName(), driverName);
156b89395b1SShawn McCarney EXPECT_EQ(device.getInstance(), instance);
157b89395b1SShawn McCarney EXPECT_NE(&(device.getPMBusInterface()), nullptr);
158b89395b1SShawn McCarney }
159b89395b1SShawn McCarney }
160b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetBus)161b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetBus)
162b89395b1SShawn McCarney {
163b89395b1SShawn McCarney MockServices services;
164b89395b1SShawn McCarney
165b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
166b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
167b89395b1SShawn McCarney uint8_t bus{4};
168b89395b1SShawn McCarney uint16_t address{0x72};
169b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus, address};
170b89395b1SShawn McCarney
171b89395b1SShawn McCarney EXPECT_EQ(device.getBus(), bus);
172b89395b1SShawn McCarney }
173b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetAddress)174b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetAddress)
175b89395b1SShawn McCarney {
176b89395b1SShawn McCarney MockServices services;
177b89395b1SShawn McCarney
178b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
179b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
180b89395b1SShawn McCarney uint8_t bus{3};
181b89395b1SShawn McCarney uint16_t address{0xab};
182b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus, address};
183b89395b1SShawn McCarney
184b89395b1SShawn McCarney EXPECT_EQ(device.getAddress(), address);
185b89395b1SShawn McCarney }
186b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetDriverName)187b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetDriverName)
188b89395b1SShawn McCarney {
189b89395b1SShawn McCarney MockServices services;
190b89395b1SShawn McCarney
191b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
192b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
193b89395b1SShawn McCarney uint8_t bus{3};
194b89395b1SShawn McCarney uint16_t address{0x72};
195b89395b1SShawn McCarney std::string driverName{"xyzdev"};
196b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services,
197b89395b1SShawn McCarney bus, address, driverName};
198b89395b1SShawn McCarney
199b89395b1SShawn McCarney EXPECT_EQ(device.getDriverName(), driverName);
200b89395b1SShawn McCarney }
201b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetInstance)202b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetInstance)
203b89395b1SShawn McCarney {
204b89395b1SShawn McCarney MockServices services;
205b89395b1SShawn McCarney
206b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
207b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
208b89395b1SShawn McCarney uint8_t bus{3};
209b89395b1SShawn McCarney uint16_t address{0x72};
210b89395b1SShawn McCarney std::string driverName{"xyzdev"};
211b89395b1SShawn McCarney size_t instance{3};
212b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
213b89395b1SShawn McCarney address, driverName, instance};
214b89395b1SShawn McCarney
215b89395b1SShawn McCarney EXPECT_EQ(device.getInstance(), instance);
216b89395b1SShawn McCarney }
217b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetPMBusInterface)218b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetPMBusInterface)
219b89395b1SShawn McCarney {
220b89395b1SShawn McCarney MockServices services;
221b89395b1SShawn McCarney
222b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
223b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
224b89395b1SShawn McCarney uint8_t bus{3};
225b89395b1SShawn McCarney uint16_t address{0x72};
226b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus, address};
227b89395b1SShawn McCarney
228b89395b1SShawn McCarney EXPECT_NE(&(device.getPMBusInterface()), nullptr);
229b89395b1SShawn McCarney }
230b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetGPIOValues)231b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetGPIOValues)
232b89395b1SShawn McCarney {
233b89395b1SShawn McCarney // Test where works
234b89395b1SShawn McCarney {
235b89395b1SShawn McCarney MockServices services;
236b89395b1SShawn McCarney std::vector<int> gpioValues{1, 1, 1};
237b89395b1SShawn McCarney EXPECT_CALL(services, getGPIOValues("abc_382%#, zy"))
238b89395b1SShawn McCarney .Times(1)
239b89395b1SShawn McCarney .WillOnce(Return(gpioValues));
240b89395b1SShawn McCarney
241b89395b1SShawn McCarney std::string name{"ABC_382%#, ZY"};
242b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
243b89395b1SShawn McCarney uint8_t bus{3};
244b89395b1SShawn McCarney uint16_t address{0x72};
245b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
246b89395b1SShawn McCarney address};
247b89395b1SShawn McCarney
248b89395b1SShawn McCarney EXPECT_TRUE(device.getGPIOValues(services) == gpioValues);
249b89395b1SShawn McCarney }
250b89395b1SShawn McCarney
251b89395b1SShawn McCarney // Test where fails with exception
252b89395b1SShawn McCarney {
253b89395b1SShawn McCarney MockServices services;
254b89395b1SShawn McCarney EXPECT_CALL(services, getGPIOValues("xyz_pseq"))
255b89395b1SShawn McCarney .Times(1)
256b89395b1SShawn McCarney .WillOnce(
257b89395b1SShawn McCarney Throw(std::runtime_error{"libgpiod: Unable to open chip"}));
258b89395b1SShawn McCarney
259b89395b1SShawn McCarney std::string name{"XYZ_PSEQ"};
260b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
261b89395b1SShawn McCarney uint8_t bus{3};
262b89395b1SShawn McCarney uint16_t address{0x72};
263b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
264b89395b1SShawn McCarney address};
265b89395b1SShawn McCarney
266b89395b1SShawn McCarney try
267b89395b1SShawn McCarney {
268b89395b1SShawn McCarney device.getGPIOValues(services);
269b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
270b89395b1SShawn McCarney }
271b89395b1SShawn McCarney catch (const std::exception& e)
272b89395b1SShawn McCarney {
273b89395b1SShawn McCarney EXPECT_STREQ(e.what(),
274b89395b1SShawn McCarney "Unable to read GPIO values from device XYZ_PSEQ "
275b89395b1SShawn McCarney "using label xyz_pseq: "
276b89395b1SShawn McCarney "libgpiod: Unable to open chip");
277b89395b1SShawn McCarney }
278b89395b1SShawn McCarney }
279b89395b1SShawn McCarney }
280b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetStatusWord)281b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetStatusWord)
282b89395b1SShawn McCarney {
283b89395b1SShawn McCarney // Test where works
284b89395b1SShawn McCarney {
285b89395b1SShawn McCarney MockServices services;
286b89395b1SShawn McCarney
287b89395b1SShawn McCarney std::string name{"xyz_pseq"};
288b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
289b89395b1SShawn McCarney uint8_t bus{3};
290b89395b1SShawn McCarney uint16_t address{0x72};
291b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
292b89395b1SShawn McCarney address};
293b89395b1SShawn McCarney
294b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
295b89395b1SShawn McCarney EXPECT_CALL(pmbus, read("status13", Type::Debug, true))
296b89395b1SShawn McCarney .Times(1)
297b89395b1SShawn McCarney .WillOnce(Return(0x1234));
298b89395b1SShawn McCarney
299b89395b1SShawn McCarney uint8_t page{13};
300b89395b1SShawn McCarney EXPECT_EQ(device.getStatusWord(page), 0x1234);
301b89395b1SShawn McCarney }
302b89395b1SShawn McCarney
303b89395b1SShawn McCarney // Test where fails with exception
304b89395b1SShawn McCarney {
305b89395b1SShawn McCarney MockServices services;
306b89395b1SShawn McCarney
307b89395b1SShawn McCarney std::string name{"xyz_pseq"};
308b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
309b89395b1SShawn McCarney uint8_t bus{3};
310b89395b1SShawn McCarney uint16_t address{0x72};
311b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
312b89395b1SShawn McCarney address};
313b89395b1SShawn McCarney
314b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
315b89395b1SShawn McCarney EXPECT_CALL(pmbus, read("status0", Type::Debug, true))
316b89395b1SShawn McCarney .Times(1)
317b89395b1SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
318b89395b1SShawn McCarney
319b89395b1SShawn McCarney try
320b89395b1SShawn McCarney {
321b89395b1SShawn McCarney uint8_t page{0};
322b89395b1SShawn McCarney device.getStatusWord(page);
323b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
324b89395b1SShawn McCarney }
325b89395b1SShawn McCarney catch (const std::exception& e)
326b89395b1SShawn McCarney {
327b89395b1SShawn McCarney EXPECT_STREQ(
328b89395b1SShawn McCarney e.what(),
329b89395b1SShawn McCarney "Unable to read STATUS_WORD for PAGE 0 of device xyz_pseq: "
330b89395b1SShawn McCarney "File does not exist");
331b89395b1SShawn McCarney }
332b89395b1SShawn McCarney }
333b89395b1SShawn McCarney }
334b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetStatusVout)335b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetStatusVout)
336b89395b1SShawn McCarney {
337b89395b1SShawn McCarney // Test where works
338b89395b1SShawn McCarney {
339b89395b1SShawn McCarney MockServices services;
340b89395b1SShawn McCarney
341b89395b1SShawn McCarney std::string name{"xyz_pseq"};
342b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
343b89395b1SShawn McCarney uint8_t bus{3};
344b89395b1SShawn McCarney uint16_t address{0x72};
345b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
346b89395b1SShawn McCarney address};
347b89395b1SShawn McCarney
348b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
349b89395b1SShawn McCarney EXPECT_CALL(pmbus, read("status13_vout", Type::Debug, true))
350b89395b1SShawn McCarney .Times(1)
351b89395b1SShawn McCarney .WillOnce(Return(0xde));
352b89395b1SShawn McCarney
353b89395b1SShawn McCarney uint8_t page{13};
354b89395b1SShawn McCarney EXPECT_EQ(device.getStatusVout(page), 0xde);
355b89395b1SShawn McCarney }
356b89395b1SShawn McCarney
357b89395b1SShawn McCarney // Test where fails with exception
358b89395b1SShawn McCarney {
359b89395b1SShawn McCarney MockServices services;
360b89395b1SShawn McCarney
361b89395b1SShawn McCarney std::string name{"xyz_pseq"};
362b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
363b89395b1SShawn McCarney uint8_t bus{3};
364b89395b1SShawn McCarney uint16_t address{0x72};
365b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
366b89395b1SShawn McCarney address};
367b89395b1SShawn McCarney
368b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
369b89395b1SShawn McCarney EXPECT_CALL(pmbus, read("status0_vout", Type::Debug, true))
370b89395b1SShawn McCarney .Times(1)
371b89395b1SShawn McCarney .WillOnce(Throw(std::runtime_error{"File does not exist"}));
372b89395b1SShawn McCarney
373b89395b1SShawn McCarney try
374b89395b1SShawn McCarney {
375b89395b1SShawn McCarney uint8_t page{0};
376b89395b1SShawn McCarney device.getStatusVout(page);
377b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
378b89395b1SShawn McCarney }
379b89395b1SShawn McCarney catch (const std::exception& e)
380b89395b1SShawn McCarney {
381b89395b1SShawn McCarney EXPECT_STREQ(
382b89395b1SShawn McCarney e.what(),
383b89395b1SShawn McCarney "Unable to read STATUS_VOUT for PAGE 0 of device xyz_pseq: "
384b89395b1SShawn McCarney "File does not exist");
385b89395b1SShawn McCarney }
386b89395b1SShawn McCarney }
387b89395b1SShawn McCarney }
388b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetReadVout)389b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetReadVout)
390b89395b1SShawn McCarney {
391b89395b1SShawn McCarney // Test where works
392b89395b1SShawn McCarney {
393b89395b1SShawn McCarney // Create simulated hwmon voltage label file
394b89395b1SShawn McCarney createFile("in13_label"); // PAGE 9 -> file number 13
395b89395b1SShawn McCarney
396b89395b1SShawn McCarney MockServices services;
397b89395b1SShawn McCarney
398b89395b1SShawn McCarney std::string name{"xyz_pseq"};
399b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
400b89395b1SShawn McCarney uint8_t bus{3};
401b89395b1SShawn McCarney uint16_t address{0x72};
402b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
403b89395b1SShawn McCarney address};
404b89395b1SShawn McCarney
405b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
406b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
407b89395b1SShawn McCarney .Times(1)
408e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
409b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
410b89395b1SShawn McCarney .Times(1)
411b89395b1SShawn McCarney .WillOnce(Return("vout10")); // PAGE number 9 + 1
412b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_input", Type::Hwmon))
413b89395b1SShawn McCarney .Times(1)
414b89395b1SShawn McCarney .WillOnce(Return("851"));
415b89395b1SShawn McCarney
416b89395b1SShawn McCarney uint8_t page{9};
417b89395b1SShawn McCarney EXPECT_EQ(device.getReadVout(page), 0.851);
418b89395b1SShawn McCarney }
419b89395b1SShawn McCarney
420b89395b1SShawn McCarney // Test where fails
421b89395b1SShawn McCarney {
422b89395b1SShawn McCarney // Create simulated hwmon voltage label file
423b89395b1SShawn McCarney createFile("in13_label"); // PAGE 8 -> file number 13
424b89395b1SShawn McCarney
425b89395b1SShawn McCarney MockServices services;
426b89395b1SShawn McCarney
427b89395b1SShawn McCarney std::string name{"xyz_pseq"};
428b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
429b89395b1SShawn McCarney uint8_t bus{3};
430b89395b1SShawn McCarney uint16_t address{0x72};
431b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
432b89395b1SShawn McCarney address};
433b89395b1SShawn McCarney
434b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
435b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
436b89395b1SShawn McCarney .Times(1)
437e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
438b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
439b89395b1SShawn McCarney .Times(1)
440b89395b1SShawn McCarney .WillOnce(Return("vout9")); // PAGE number 8 + 1
441b89395b1SShawn McCarney
442b89395b1SShawn McCarney try
443b89395b1SShawn McCarney {
444b89395b1SShawn McCarney uint8_t page{9};
445b89395b1SShawn McCarney device.getReadVout(page);
446b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
447b89395b1SShawn McCarney }
448b89395b1SShawn McCarney catch (const std::exception& e)
449b89395b1SShawn McCarney {
450b89395b1SShawn McCarney EXPECT_STREQ(
451b89395b1SShawn McCarney e.what(),
452b89395b1SShawn McCarney "Unable to read READ_VOUT for PAGE 9 of device xyz_pseq: "
453b89395b1SShawn McCarney "Unable to find hwmon file number for PAGE 9 of device xyz_pseq");
454b89395b1SShawn McCarney }
455b89395b1SShawn McCarney }
456b89395b1SShawn McCarney }
457b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetVoutUVFaultLimit)458b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetVoutUVFaultLimit)
459b89395b1SShawn McCarney {
460b89395b1SShawn McCarney // Test where works
461b89395b1SShawn McCarney {
462b89395b1SShawn McCarney // Create simulated hwmon voltage label file
463b89395b1SShawn McCarney createFile("in1_label"); // PAGE 6 -> file number 1
464b89395b1SShawn McCarney
465b89395b1SShawn McCarney MockServices services;
466b89395b1SShawn McCarney
467b89395b1SShawn McCarney std::string name{"xyz_pseq"};
468b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
469b89395b1SShawn McCarney uint8_t bus{3};
470b89395b1SShawn McCarney uint16_t address{0x72};
471b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
472b89395b1SShawn McCarney address};
473b89395b1SShawn McCarney
474b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
475b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
476b89395b1SShawn McCarney .Times(1)
477e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
478b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
479b89395b1SShawn McCarney .Times(1)
480b89395b1SShawn McCarney .WillOnce(Return("vout7")); // PAGE number 6 + 1
481b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in1_lcrit", Type::Hwmon))
482b89395b1SShawn McCarney .Times(1)
483b89395b1SShawn McCarney .WillOnce(Return("1329"));
484b89395b1SShawn McCarney
485b89395b1SShawn McCarney uint8_t page{6};
486b89395b1SShawn McCarney EXPECT_EQ(device.getVoutUVFaultLimit(page), 1.329);
487b89395b1SShawn McCarney }
488b89395b1SShawn McCarney
489b89395b1SShawn McCarney // Test where fails
490b89395b1SShawn McCarney {
491b89395b1SShawn McCarney // Create simulated hwmon voltage label file
492b89395b1SShawn McCarney createFile("in1_label"); // PAGE 7 -> file number 1
493b89395b1SShawn McCarney
494b89395b1SShawn McCarney MockServices services;
495b89395b1SShawn McCarney
496b89395b1SShawn McCarney std::string name{"xyz_pseq"};
497b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
498b89395b1SShawn McCarney uint8_t bus{3};
499b89395b1SShawn McCarney uint16_t address{0x72};
500b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
501b89395b1SShawn McCarney address};
502b89395b1SShawn McCarney
503b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
504b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
505b89395b1SShawn McCarney .Times(1)
506e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
507b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
508b89395b1SShawn McCarney .Times(1)
509b89395b1SShawn McCarney .WillOnce(Return("vout8")); // PAGE number 7 + 1
510b89395b1SShawn McCarney
511b89395b1SShawn McCarney try
512b89395b1SShawn McCarney {
513b89395b1SShawn McCarney uint8_t page{6};
514b89395b1SShawn McCarney device.getVoutUVFaultLimit(page);
515b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
516b89395b1SShawn McCarney }
517b89395b1SShawn McCarney catch (const std::exception& e)
518b89395b1SShawn McCarney {
519b89395b1SShawn McCarney EXPECT_STREQ(
520b89395b1SShawn McCarney e.what(),
521b89395b1SShawn McCarney "Unable to read VOUT_UV_FAULT_LIMIT for PAGE 6 of device xyz_pseq: "
522b89395b1SShawn McCarney "Unable to find hwmon file number for PAGE 6 of device xyz_pseq");
523b89395b1SShawn McCarney }
524b89395b1SShawn McCarney }
525b89395b1SShawn McCarney }
526b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetPageToFileNumberMap)527b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetPageToFileNumberMap)
528b89395b1SShawn McCarney {
529b89395b1SShawn McCarney // Test where works: No voltage label files/mappings found
530b89395b1SShawn McCarney {
531b89395b1SShawn McCarney // Create simulated hwmon files. None are valid voltage label files.
532b89395b1SShawn McCarney createFile("in1_input"); // Not a label file
533b89395b1SShawn McCarney createFile("in9_lcrit"); // Not a label file
534b89395b1SShawn McCarney createFile("in_label"); // Invalid voltage label file name
535b89395b1SShawn McCarney createFile("in9a_label"); // Invalid voltage label file name
536b89395b1SShawn McCarney createFile("fan3_label"); // Not a voltage label file
537b89395b1SShawn McCarney createFile("temp8_label"); // Not a voltage label file
538b89395b1SShawn McCarney
539b89395b1SShawn McCarney MockServices services;
540b89395b1SShawn McCarney
541b89395b1SShawn McCarney std::string name{"xyz_pseq"};
542b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
543b89395b1SShawn McCarney uint8_t bus{3};
544b89395b1SShawn McCarney uint16_t address{0x72};
545b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
546b89395b1SShawn McCarney address};
547b89395b1SShawn McCarney
548b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
549b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
550b89395b1SShawn McCarney .Times(1)
551e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
552b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString).Times(0);
553b89395b1SShawn McCarney
554b89395b1SShawn McCarney const std::map<uint8_t, unsigned int>& map =
555b89395b1SShawn McCarney device.getPageToFileNumberMap();
556b89395b1SShawn McCarney EXPECT_TRUE(map.empty());
557b89395b1SShawn McCarney }
558b89395b1SShawn McCarney
559b89395b1SShawn McCarney // Test where works: Multiple voltage label files/mappings found
560b89395b1SShawn McCarney {
561b89395b1SShawn McCarney // Create simulated hwmon files
562b89395b1SShawn McCarney createFile("in9_label"); // PAGE 3 -> file number 9
563b89395b1SShawn McCarney createFile("in13_label"); // PAGE 7 -> file number 13
564b89395b1SShawn McCarney createFile("in0_label"); // PAGE 12 -> file number 0
565b89395b1SShawn McCarney createFile("in11_label"); // No mapping; invalid contents
566b89395b1SShawn McCarney createFile("in12_label"); // No mapping; invalid contents
567b89395b1SShawn McCarney createFile("in1_input"); // Not a label file
568b89395b1SShawn McCarney createFile("in7_lcrit"); // Not a label file
569b89395b1SShawn McCarney createFile("fan3_label"); // Not a voltage label file
570b89395b1SShawn McCarney createFile("temp8_label"); // Not a voltage label file
571b89395b1SShawn McCarney
572b89395b1SShawn McCarney MockServices services;
573b89395b1SShawn McCarney
574b89395b1SShawn McCarney std::string name{"xyz_pseq"};
575b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
576b89395b1SShawn McCarney uint8_t bus{3};
577b89395b1SShawn McCarney uint16_t address{0x72};
578b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
579b89395b1SShawn McCarney address};
580b89395b1SShawn McCarney
581b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
582b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
583b89395b1SShawn McCarney .Times(1)
584e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
585b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in9_label", Type::Hwmon))
586b89395b1SShawn McCarney .Times(1)
587b89395b1SShawn McCarney .WillOnce(Return("vout4")); // PAGE number 3 + 1
588b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
589b89395b1SShawn McCarney .Times(1)
590b89395b1SShawn McCarney .WillOnce(Return("vout8")); // PAGE number 7 + 1
591b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
592b89395b1SShawn McCarney .Times(1)
593b89395b1SShawn McCarney .WillOnce(Return("vout13")); // PAGE number 12 + 1
594b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in11_label", Type::Hwmon))
595b89395b1SShawn McCarney .Times(1)
596b89395b1SShawn McCarney .WillOnce(Return("vout")); // Invalid format
597b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in12_label", Type::Hwmon))
598b89395b1SShawn McCarney .Times(1)
599b89395b1SShawn McCarney .WillOnce(Return("vout13a")); // Invalid format
600b89395b1SShawn McCarney
601b89395b1SShawn McCarney const std::map<uint8_t, unsigned int>& map =
602b89395b1SShawn McCarney device.getPageToFileNumberMap();
603b89395b1SShawn McCarney EXPECT_EQ(map.size(), 3);
604b89395b1SShawn McCarney EXPECT_EQ(map.at(uint8_t{3}), 9);
605b89395b1SShawn McCarney EXPECT_EQ(map.at(uint8_t{7}), 13);
606b89395b1SShawn McCarney EXPECT_EQ(map.at(uint8_t{12}), 0);
607b89395b1SShawn McCarney }
608b89395b1SShawn McCarney
609b89395b1SShawn McCarney // Test where fails: hwmon directory path is actually a file
610b89395b1SShawn McCarney {
611b89395b1SShawn McCarney // Create file that will be returned as the hwmon directory path
612b89395b1SShawn McCarney createFile("in9_label");
613b89395b1SShawn McCarney
614b89395b1SShawn McCarney MockServices services;
615b89395b1SShawn McCarney
616b89395b1SShawn McCarney std::string name{"xyz_pseq"};
617b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
618b89395b1SShawn McCarney uint8_t bus{3};
619b89395b1SShawn McCarney uint16_t address{0x72};
620b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
621b89395b1SShawn McCarney address};
622b89395b1SShawn McCarney
623b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
624b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
625b89395b1SShawn McCarney .Times(1)
626e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath / "in9_label"));
627b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString).Times(0);
628b89395b1SShawn McCarney
629b89395b1SShawn McCarney const std::map<uint8_t, unsigned int>& map =
630b89395b1SShawn McCarney device.getPageToFileNumberMap();
631b89395b1SShawn McCarney EXPECT_TRUE(map.empty());
632b89395b1SShawn McCarney }
633b89395b1SShawn McCarney
634b89395b1SShawn McCarney // Test where fails: hwmon directory path does not exist
635b89395b1SShawn McCarney {
636b89395b1SShawn McCarney MockServices services;
637b89395b1SShawn McCarney
638b89395b1SShawn McCarney std::string name{"xyz_pseq"};
639b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
640b89395b1SShawn McCarney uint8_t bus{3};
641b89395b1SShawn McCarney uint16_t address{0x72};
642b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
643b89395b1SShawn McCarney address};
644b89395b1SShawn McCarney
645b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
646b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
647b89395b1SShawn McCarney .Times(1)
648e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath / "does_not_exist"));
649b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString).Times(0);
650b89395b1SShawn McCarney
651b89395b1SShawn McCarney const std::map<uint8_t, unsigned int>& map =
652b89395b1SShawn McCarney device.getPageToFileNumberMap();
653b89395b1SShawn McCarney EXPECT_TRUE(map.empty());
654b89395b1SShawn McCarney }
655b89395b1SShawn McCarney
656b89395b1SShawn McCarney // Test where fails: hwmon directory path is not readable
657b89395b1SShawn McCarney {
658b89395b1SShawn McCarney // Create simulated hwmon files
659b89395b1SShawn McCarney createFile("in9_label");
660b89395b1SShawn McCarney createFile("in13_label");
661b89395b1SShawn McCarney createFile("in0_label");
662b89395b1SShawn McCarney
663b89395b1SShawn McCarney // Change temporary directory to be unreadable
664e9144ab4SShawn McCarney fs::permissions(tempDirPath, fs::perms::none);
665b89395b1SShawn McCarney
666b89395b1SShawn McCarney MockServices services;
667b89395b1SShawn McCarney
668b89395b1SShawn McCarney std::string name{"xyz_pseq"};
669b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
670b89395b1SShawn McCarney uint8_t bus{3};
671b89395b1SShawn McCarney uint16_t address{0x72};
672b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
673b89395b1SShawn McCarney address};
674b89395b1SShawn McCarney
675b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
676b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
677b89395b1SShawn McCarney .Times(1)
678e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
679b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString).Times(0);
680b89395b1SShawn McCarney
681b89395b1SShawn McCarney try
682b89395b1SShawn McCarney {
683b89395b1SShawn McCarney device.getPageToFileNumberMap();
684b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
685b89395b1SShawn McCarney }
686b89395b1SShawn McCarney catch (const std::exception& e)
687b89395b1SShawn McCarney {
688b89395b1SShawn McCarney // Error message varies
689b89395b1SShawn McCarney }
690b89395b1SShawn McCarney
691b89395b1SShawn McCarney // Change temporary directory to be readable/writable
692e9144ab4SShawn McCarney fs::permissions(tempDirPath, fs::perms::owner_all);
693b89395b1SShawn McCarney }
694b89395b1SShawn McCarney }
695b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,GetFileNumber)696b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, GetFileNumber)
697b89395b1SShawn McCarney {
698b89395b1SShawn McCarney // Test where works
699b89395b1SShawn McCarney {
700b89395b1SShawn McCarney // Create simulated hwmon voltage label files
701b89395b1SShawn McCarney createFile("in0_label"); // PAGE 6 -> file number 0
702b89395b1SShawn McCarney createFile("in13_label"); // PAGE 9 -> file number 13
703b89395b1SShawn McCarney
704b89395b1SShawn McCarney MockServices services;
705b89395b1SShawn McCarney
706b89395b1SShawn McCarney std::string name{"xyz_pseq"};
707b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
708b89395b1SShawn McCarney uint8_t bus{3};
709b89395b1SShawn McCarney uint16_t address{0x72};
710b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
711b89395b1SShawn McCarney address};
712b89395b1SShawn McCarney
713b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
714b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
715b89395b1SShawn McCarney .Times(1)
716e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
717b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
718b89395b1SShawn McCarney .Times(1)
719b89395b1SShawn McCarney .WillOnce(Return("vout7")); // PAGE number 6 + 1
720b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
721b89395b1SShawn McCarney .Times(1)
722b89395b1SShawn McCarney .WillOnce(Return("vout10")); // PAGE number 9 + 1
723b89395b1SShawn McCarney
724b89395b1SShawn McCarney // Map was empty and needs to be built
725b89395b1SShawn McCarney uint8_t page{6};
726b89395b1SShawn McCarney EXPECT_EQ(device.getFileNumber(page), 0);
727b89395b1SShawn McCarney
728b89395b1SShawn McCarney // Map had already been built
729b89395b1SShawn McCarney page = 9;
730b89395b1SShawn McCarney EXPECT_EQ(device.getFileNumber(page), 13);
731b89395b1SShawn McCarney }
732b89395b1SShawn McCarney
733b89395b1SShawn McCarney // Test where fails: No mapping for specified PMBus PAGE
734b89395b1SShawn McCarney {
735b89395b1SShawn McCarney // Create simulated hwmon voltage label files
736b89395b1SShawn McCarney createFile("in0_label"); // PAGE 6 -> file number 0
737b89395b1SShawn McCarney createFile("in13_label"); // PAGE 9 -> file number 13
738b89395b1SShawn McCarney
739b89395b1SShawn McCarney MockServices services;
740b89395b1SShawn McCarney
741b89395b1SShawn McCarney std::string name{"xyz_pseq"};
742b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
743b89395b1SShawn McCarney uint8_t bus{3};
744b89395b1SShawn McCarney uint16_t address{0x72};
745b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus,
746b89395b1SShawn McCarney address};
747b89395b1SShawn McCarney
748b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
749b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
750b89395b1SShawn McCarney .Times(1)
751e9144ab4SShawn McCarney .WillOnce(Return(tempDirPath));
752b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in0_label", Type::Hwmon))
753b89395b1SShawn McCarney .Times(1)
754b89395b1SShawn McCarney .WillOnce(Return("vout7")); // PAGE number 6 + 1
755b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in13_label", Type::Hwmon))
756b89395b1SShawn McCarney .Times(1)
757b89395b1SShawn McCarney .WillOnce(Return("vout10")); // PAGE number 9 + 1
758b89395b1SShawn McCarney
759b89395b1SShawn McCarney try
760b89395b1SShawn McCarney {
761b89395b1SShawn McCarney uint8_t page{13};
762b89395b1SShawn McCarney device.getFileNumber(page);
763b89395b1SShawn McCarney ADD_FAILURE() << "Should not have reached this line.";
764b89395b1SShawn McCarney }
765b89395b1SShawn McCarney catch (const std::exception& e)
766b89395b1SShawn McCarney {
767b89395b1SShawn McCarney EXPECT_STREQ(
768b89395b1SShawn McCarney e.what(),
769b89395b1SShawn McCarney "Unable to find hwmon file number for PAGE 13 of device xyz_pseq");
770b89395b1SShawn McCarney }
771b89395b1SShawn McCarney }
772b89395b1SShawn McCarney }
773b89395b1SShawn McCarney
TEST_F(PMBusDriverDeviceTests,PrepareForPgoodFaultDetection)774b89395b1SShawn McCarney TEST_F(PMBusDriverDeviceTests, PrepareForPgoodFaultDetection)
775b89395b1SShawn McCarney {
776b89395b1SShawn McCarney // This is a protected method and cannot be called directly from a gtest.
777b89395b1SShawn McCarney // Call findPgoodFault() which calls prepareForPgoodFaultDetection().
778b89395b1SShawn McCarney
779b89395b1SShawn McCarney // Create simulated hwmon voltage label file
780b89395b1SShawn McCarney createFile("in1_label"); // PAGE 6 -> file number 1
781b89395b1SShawn McCarney
782b89395b1SShawn McCarney MockServices services;
78371d7fe43SShawn McCarney std::vector<int> gpioValues{1, 1, 1};
78471d7fe43SShawn McCarney EXPECT_CALL(services, getGPIOValues("xyz_pseq"))
78571d7fe43SShawn McCarney .Times(1)
78671d7fe43SShawn McCarney .WillOnce(Return(gpioValues));
787b89395b1SShawn McCarney
788b89395b1SShawn McCarney std::string name{"xyz_pseq"};
789b89395b1SShawn McCarney std::vector<std::unique_ptr<Rail>> rails;
790b89395b1SShawn McCarney uint8_t bus{3};
791b89395b1SShawn McCarney uint16_t address{0x72};
792b89395b1SShawn McCarney PMBusDriverDevice device{name, std::move(rails), services, bus, address};
793b89395b1SShawn McCarney
794b89395b1SShawn McCarney // Methods that get hwmon file info should be called twice
795b89395b1SShawn McCarney MockPMBus& pmbus = static_cast<MockPMBus&>(device.getPMBusInterface());
796b89395b1SShawn McCarney EXPECT_CALL(pmbus, getPath(Type::Hwmon))
797b89395b1SShawn McCarney .Times(2)
798e9144ab4SShawn McCarney .WillRepeatedly(Return(tempDirPath));
799b89395b1SShawn McCarney EXPECT_CALL(pmbus, readString("in1_label", Type::Hwmon))
800b89395b1SShawn McCarney .Times(2)
801b89395b1SShawn McCarney .WillRepeatedly(Return("vout7")); // PAGE number 6 + 1
802b89395b1SShawn McCarney
803b89395b1SShawn McCarney // Map was empty and needs to be built
804b89395b1SShawn McCarney uint8_t page{6};
805b89395b1SShawn McCarney EXPECT_EQ(device.getFileNumber(page), 1);
806b89395b1SShawn McCarney
807b89395b1SShawn McCarney // Call findPgoodFault() which calls prepareForPgoodFaultDetection() which
808b89395b1SShawn McCarney // rebuilds the map.
809b89395b1SShawn McCarney std::string powerSupplyError{};
810b89395b1SShawn McCarney std::map<std::string, std::string> additionalData{};
811*f5402197SPatrick Williams std::string error =
812*f5402197SPatrick Williams device.findPgoodFault(services, powerSupplyError, additionalData);
813b89395b1SShawn McCarney EXPECT_TRUE(error.empty());
814b89395b1SShawn McCarney EXPECT_EQ(additionalData.size(), 0);
815b89395b1SShawn McCarney
816b89395b1SShawn McCarney EXPECT_EQ(device.getFileNumber(page), 1);
817b89395b1SShawn McCarney }
818