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