xref: /openbmc/gpioplus/test/chip.cpp (revision 7ba248ad)
1 #include <fcntl.h>
2 #include <linux/gpio.h>
3 
4 #include <gpioplus/chip.hpp>
5 #include <gpioplus/test/sys.hpp>
6 
7 #include <cerrno>
8 #include <cstdint>
9 #include <cstring>
10 #include <memory>
11 #include <system_error>
12 
13 #include <gmock/gmock.h>
14 #include <gtest/gtest.h>
15 
16 namespace gpioplus
17 {
18 namespace
19 {
20 
21 using testing::DoAll;
22 using testing::Return;
23 using testing::SaveArgPointee;
24 using testing::SetArgPointee;
25 using testing::StrEq;
26 
TEST(LineFlagsTest,LineFlagsFromFlags)27 TEST(LineFlagsTest, LineFlagsFromFlags)
28 {
29     LineFlags line_flags(GPIOLINE_FLAG_KERNEL | GPIOLINE_FLAG_OPEN_DRAIN |
30                          GPIOLINE_FLAG_OPEN_SOURCE);
31     EXPECT_TRUE(line_flags.kernel);
32     EXPECT_FALSE(line_flags.output);
33     EXPECT_FALSE(line_flags.active_low);
34     EXPECT_TRUE(line_flags.open_drain);
35     EXPECT_TRUE(line_flags.open_source);
36 
37     line_flags = GPIOLINE_FLAG_IS_OUT | GPIOLINE_FLAG_ACTIVE_LOW;
38     EXPECT_FALSE(line_flags.kernel);
39     EXPECT_TRUE(line_flags.output);
40     EXPECT_TRUE(line_flags.active_low);
41     EXPECT_FALSE(line_flags.open_drain);
42     EXPECT_FALSE(line_flags.open_source);
43 }
44 
45 class ChipMethodTest : public testing::Test
46 {
47   protected:
48     const int expected_fd = 1234;
49     testing::StrictMock<test::SysMock> mock;
50     std::unique_ptr<Chip> chip;
51 
SetUp()52     void SetUp()
53     {
54         const int chip_id = 1;
55         const char* path = "/dev/gpiochip1";
56 
57         EXPECT_CALL(mock, open(StrEq(path), O_RDONLY | O_CLOEXEC))
58             .WillOnce(Return(expected_fd));
59         chip = std::make_unique<Chip>(chip_id, &mock);
60     }
61 
TearDown()62     void TearDown()
63     {
64         EXPECT_CALL(mock, close(expected_fd)).WillOnce(Return(0));
65         chip.reset();
66     }
67 };
68 
TEST_F(ChipMethodTest,Basic)69 TEST_F(ChipMethodTest, Basic)
70 {
71     EXPECT_EQ(expected_fd, *chip->getFd());
72     EXPECT_EQ(&mock, chip->getFd().getSys());
73 }
74 
TEST_F(ChipMethodTest,GetChipInfoSuccess)75 TEST_F(ChipMethodTest, GetChipInfoSuccess)
76 {
77     const ChipInfo expected_info{"name", "label", 31};
78     struct gpiochip_info info;
79     ASSERT_LE(expected_info.name.size(), sizeof(info.name));
80     strcpy(info.name, expected_info.name.c_str());
81     ASSERT_LE(expected_info.label.size(), sizeof(info.label));
82     strcpy(info.label, expected_info.label.c_str());
83     info.lines = expected_info.lines;
84 
85     EXPECT_CALL(mock, gpio_get_chipinfo(expected_fd, testing::_))
86         .WillOnce(DoAll(SetArgPointee<1>(info), Return(0)));
87     ChipInfo retrieved_info = chip->getChipInfo();
88     EXPECT_EQ(expected_info.name, retrieved_info.name);
89     EXPECT_EQ(expected_info.label, retrieved_info.label);
90     EXPECT_EQ(expected_info.lines, retrieved_info.lines);
91 }
92 
TEST_F(ChipMethodTest,GetChipInfoFail)93 TEST_F(ChipMethodTest, GetChipInfoFail)
94 {
95     EXPECT_CALL(mock, gpio_get_chipinfo(expected_fd, testing::_))
96         .WillOnce(Return(-EINVAL));
97     EXPECT_THROW(chip->getChipInfo(), std::system_error);
98 }
99 
TEST_F(ChipMethodTest,GetLineInfoSuccess)100 TEST_F(ChipMethodTest, GetLineInfoSuccess)
101 {
102     const uint32_t line = 176;
103     const LineInfo expected_info{GPIOLINE_FLAG_ACTIVE_LOW, "name", "consumer"};
104     struct gpioline_info info, req;
105     info.flags = GPIOLINE_FLAG_ACTIVE_LOW;
106     ASSERT_LE(expected_info.name.size(), sizeof(info.name));
107     strcpy(info.name, expected_info.name.c_str());
108     ASSERT_LE(expected_info.consumer.size(), sizeof(info.consumer));
109     strcpy(info.consumer, expected_info.consumer.c_str());
110 
111     EXPECT_CALL(mock, gpio_get_lineinfo(expected_fd, testing::_))
112         .WillOnce(
113             DoAll(SaveArgPointee<1>(&req), SetArgPointee<1>(info), Return(0)));
114     LineInfo retrieved_info = chip->getLineInfo(line);
115     EXPECT_EQ(line, req.line_offset);
116     EXPECT_FALSE(retrieved_info.flags.kernel);
117     EXPECT_FALSE(retrieved_info.flags.output);
118     EXPECT_TRUE(retrieved_info.flags.active_low);
119     EXPECT_FALSE(retrieved_info.flags.open_drain);
120     EXPECT_FALSE(retrieved_info.flags.open_source);
121     EXPECT_EQ(expected_info.name, retrieved_info.name);
122     EXPECT_EQ(expected_info.consumer, retrieved_info.consumer);
123 }
124 
TEST_F(ChipMethodTest,GetLineInfoFail)125 TEST_F(ChipMethodTest, GetLineInfoFail)
126 {
127     const uint32_t line = 143;
128 
129     struct gpioline_info info;
130     EXPECT_CALL(mock, gpio_get_lineinfo(expected_fd, testing::_))
131         .WillOnce(DoAll(SaveArgPointee<1>(&info), Return(-EINVAL)));
132     EXPECT_THROW(chip->getLineInfo(line), std::system_error);
133     EXPECT_EQ(line, info.line_offset);
134 }
135 
136 } // namespace
137 } // namespace gpioplus
138