blob: aa3979f3ed45b9660e4116c8f9eee7871c0362bc [file] [log] [blame]
William A. Kennington IIId8218232018-08-16 19:46:21 -07001#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
13namespace gpioplus
14{
15namespace
16{
17
18using testing::DoAll;
19using testing::Return;
20using testing::SaveArgPointee;
21using testing::SetArgPointee;
22using testing::StrEq;
23
24TEST(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
42class 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
66TEST_F(ChipMethodTest, Basic)
67{
68 EXPECT_EQ(expected_fd, *chip->getFd());
69 EXPECT_EQ(&mock, chip->getFd().getSys());
70}
71
72TEST_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
90TEST_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
97TEST_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
122TEST_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