blob: cf1f76d0d8235b3d9bca0928c8f24394489818de [file] [log] [blame]
Patrick Williams7ba248a2023-05-10 07:51:30 -05001#include <fcntl.h>
2#include <linux/gpio.h>
3
4#include <gpioplus/chip.hpp>
5#include <gpioplus/test/sys.hpp>
6
William A. Kennington IIId8218232018-08-16 19:46:21 -07007#include <cerrno>
8#include <cstdint>
9#include <cstring>
William A. Kennington IIId8218232018-08-16 19:46:21 -070010#include <memory>
11#include <system_error>
12
Patrick Williams7ba248a2023-05-10 07:51:30 -050013#include <gmock/gmock.h>
14#include <gtest/gtest.h>
15
William A. Kennington IIId8218232018-08-16 19:46:21 -070016namespace gpioplus
17{
18namespace
19{
20
21using testing::DoAll;
22using testing::Return;
23using testing::SaveArgPointee;
24using testing::SetArgPointee;
25using testing::StrEq;
26
27TEST(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
45class 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
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
62 void TearDown()
63 {
64 EXPECT_CALL(mock, close(expected_fd)).WillOnce(Return(0));
65 chip.reset();
66 }
67};
68
69TEST_F(ChipMethodTest, Basic)
70{
71 EXPECT_EQ(expected_fd, *chip->getFd());
72 EXPECT_EQ(&mock, chip->getFd().getSys());
73}
74
75TEST_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
93TEST_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
100TEST_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
125TEST_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