blob: 492c69983fcf9b58d10d082246459fd9b5af0af3 [file] [log] [blame]
Patrick Venture4d1c6872020-10-05 10:41:26 -07001#include "internal_sys_mock.hpp"
2#include "io.hpp"
3
4#include <sys/mman.h>
5
6#include <memory>
7
8#include <gmock/gmock.h>
9#include <gtest/gtest.h>
10
11namespace host_tool
12{
13namespace
14{
15
16using ::testing::_;
17using ::testing::Eq;
18using ::testing::Return;
19using ::testing::StrEq;
20
21class DevMemTest : public ::testing::Test
22{
23 protected:
24 DevMemTest() : devmem(std::make_unique<DevMemDevice>(&sys_mock))
25 {}
26
27 internal::InternalSysMock sys_mock;
28 std::unique_ptr<DevMemDevice> devmem;
29};
30
31TEST_F(DevMemTest, OpenFromReadFails)
32{
33 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1));
34
35 char destination;
36 EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
37}
38
39TEST_F(DevMemTest, MmapFromReadFails)
40{
41 int fd = 1;
42 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
43 EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
44 EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED));
45 EXPECT_CALL(sys_mock, close(fd));
46
47 char destination;
48 EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
49}
50
51TEST_F(DevMemTest, CopiesOutOfMmap)
52{
53 int fd = 1;
54 char source = 'a';
55 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
56 EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
57 EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(&source));
58 EXPECT_CALL(sys_mock, munmap(_, _));
59 EXPECT_CALL(sys_mock, close(fd));
60
61 char destination = 'b';
62 EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
63 EXPECT_THAT(destination, Eq('a'));
64}
65
66TEST_F(DevMemTest, OpenFromWriteFails)
67{
68 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1));
69
70 char source;
71 EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
72}
73
74TEST_F(DevMemTest, MmapFromWriteFails)
75{
76 int fd = 1;
77 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
78 EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
79 EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED));
80 EXPECT_CALL(sys_mock, close(fd));
81
82 char source;
83 EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
84}
85
86TEST_F(DevMemTest, CopiesIntoMmap)
87{
88 int fd = 1;
89 char destination = 'b';
90 EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
91 EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
92 EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _))
93 .WillOnce(Return(&destination));
94 EXPECT_CALL(sys_mock, munmap(_, _));
95 EXPECT_CALL(sys_mock, close(fd));
96
97 char source = 'a';
98 EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
99 EXPECT_THAT(destination, Eq('a'));
100}
101
102class PpcMemTest : public ::testing::Test
103{
104 protected:
105 static constexpr char path[] = "/dev/fun";
106
107 PpcMemTest() : devmem(std::make_unique<PpcMemDevice>(path, &sys_mock))
108 {}
109
110 internal::InternalSysMock sys_mock;
111 std::unique_ptr<PpcMemDevice> devmem;
112};
113
114TEST_F(PpcMemTest, OpenFromReadFails)
115{
116 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1));
117
118 char destination = 'b';
119 EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
120}
121
122TEST_F(PpcMemTest, PreadFails)
123{
124 int fd = 1;
125 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
126 EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(-1));
127
128 char destination = 'b';
129 EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
130}
131
132TEST_F(PpcMemTest, PreadReadWorks)
133{
134 int fd = 1;
135 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
136 EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(0));
137 EXPECT_CALL(sys_mock, close(fd));
138
139 /* Test does not validate byte is copied because that's part of pread and
140 * not the code.
141 */
142 char destination = 'b';
143 EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
144}
145
146TEST_F(PpcMemTest, OpenFromWriteFails)
147{
148 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1));
149
150 char source = 'a';
151 EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
152}
153
154TEST_F(PpcMemTest, PwriteFails)
155{
156 int fd = 1;
157 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
158 EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(-1));
159
160 char source = 'a';
161 EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
162}
163
164TEST_F(PpcMemTest, PwriteWorks)
165{
166 int fd = 1;
167 EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
168 EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(0));
169
170 /* Test does not validate byte is copied because that's part of pwrite and
171 * not the code.
172 */
173 char source = 'a';
174 EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
175}
176
177} // namespace
178} // namespace host_tool