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