14d1c687eSPatrick Venture #include "internal_sys_mock.hpp"
24d1c687eSPatrick Venture #include "io.hpp"
34d1c687eSPatrick Venture 
44d1c687eSPatrick Venture #include <sys/mman.h>
54d1c687eSPatrick Venture 
64d1c687eSPatrick Venture #include <memory>
74d1c687eSPatrick Venture 
84d1c687eSPatrick Venture #include <gmock/gmock.h>
94d1c687eSPatrick Venture #include <gtest/gtest.h>
104d1c687eSPatrick Venture 
114d1c687eSPatrick Venture namespace host_tool
124d1c687eSPatrick Venture {
134d1c687eSPatrick Venture namespace
144d1c687eSPatrick Venture {
154d1c687eSPatrick Venture 
164d1c687eSPatrick Venture using ::testing::_;
174d1c687eSPatrick Venture using ::testing::Eq;
184d1c687eSPatrick Venture using ::testing::Return;
194d1c687eSPatrick Venture using ::testing::StrEq;
204d1c687eSPatrick Venture 
214d1c687eSPatrick Venture class DevMemTest : public ::testing::Test
224d1c687eSPatrick Venture {
234d1c687eSPatrick Venture   protected:
DevMemTest()24*1038836cSPatrick Williams     DevMemTest() : devmem(std::make_unique<DevMemDevice>(&sys_mock)) {}
254d1c687eSPatrick Venture 
264d1c687eSPatrick Venture     internal::InternalSysMock sys_mock;
274d1c687eSPatrick Venture     std::unique_ptr<DevMemDevice> devmem;
284d1c687eSPatrick Venture };
294d1c687eSPatrick Venture 
TEST_F(DevMemTest,OpenFromReadFails)304d1c687eSPatrick Venture TEST_F(DevMemTest, OpenFromReadFails)
314d1c687eSPatrick Venture {
324d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1));
334d1c687eSPatrick Venture 
344d1c687eSPatrick Venture     char destination;
354d1c687eSPatrick Venture     EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
364d1c687eSPatrick Venture }
374d1c687eSPatrick Venture 
TEST_F(DevMemTest,MmapFromReadFails)384d1c687eSPatrick Venture TEST_F(DevMemTest, MmapFromReadFails)
394d1c687eSPatrick Venture {
404d1c687eSPatrick Venture     int fd = 1;
414d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
424d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
434d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED));
444d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, close(fd));
454d1c687eSPatrick Venture 
464d1c687eSPatrick Venture     char destination;
474d1c687eSPatrick Venture     EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
484d1c687eSPatrick Venture }
494d1c687eSPatrick Venture 
TEST_F(DevMemTest,CopiesOutOfMmap)504d1c687eSPatrick Venture TEST_F(DevMemTest, CopiesOutOfMmap)
514d1c687eSPatrick Venture {
524d1c687eSPatrick Venture     int fd = 1;
534d1c687eSPatrick Venture     char source = 'a';
544d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
554d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
564d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(&source));
574d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, munmap(_, _));
584d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, close(fd));
594d1c687eSPatrick Venture 
604d1c687eSPatrick Venture     char destination = 'b';
614d1c687eSPatrick Venture     EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
624d1c687eSPatrick Venture     EXPECT_THAT(destination, Eq('a'));
634d1c687eSPatrick Venture }
644d1c687eSPatrick Venture 
TEST_F(DevMemTest,OpenFromWriteFails)654d1c687eSPatrick Venture TEST_F(DevMemTest, OpenFromWriteFails)
664d1c687eSPatrick Venture {
674d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1));
684d1c687eSPatrick Venture 
694d1c687eSPatrick Venture     char source;
704d1c687eSPatrick Venture     EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
714d1c687eSPatrick Venture }
724d1c687eSPatrick Venture 
TEST_F(DevMemTest,MmapFromWriteFails)734d1c687eSPatrick Venture TEST_F(DevMemTest, MmapFromWriteFails)
744d1c687eSPatrick Venture {
754d1c687eSPatrick Venture     int fd = 1;
764d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
774d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
784d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED));
794d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, close(fd));
804d1c687eSPatrick Venture 
814d1c687eSPatrick Venture     char source;
824d1c687eSPatrick Venture     EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
834d1c687eSPatrick Venture }
844d1c687eSPatrick Venture 
TEST_F(DevMemTest,CopiesIntoMmap)854d1c687eSPatrick Venture TEST_F(DevMemTest, CopiesIntoMmap)
864d1c687eSPatrick Venture {
874d1c687eSPatrick Venture     int fd = 1;
884d1c687eSPatrick Venture     char destination = 'b';
894d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd));
904d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096));
914d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _))
924d1c687eSPatrick Venture         .WillOnce(Return(&destination));
934d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, munmap(_, _));
944d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, close(fd));
954d1c687eSPatrick Venture 
964d1c687eSPatrick Venture     char source = 'a';
974d1c687eSPatrick Venture     EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
984d1c687eSPatrick Venture     EXPECT_THAT(destination, Eq('a'));
994d1c687eSPatrick Venture }
1004d1c687eSPatrick Venture 
1014d1c687eSPatrick Venture class PpcMemTest : public ::testing::Test
1024d1c687eSPatrick Venture {
1034d1c687eSPatrick Venture   protected:
1044d1c687eSPatrick Venture     static constexpr char path[] = "/dev/fun";
1054d1c687eSPatrick Venture 
PpcMemTest()106*1038836cSPatrick Williams     PpcMemTest() : devmem(std::make_unique<PpcMemDevice>(path, &sys_mock)) {}
1074d1c687eSPatrick Venture 
1084d1c687eSPatrick Venture     internal::InternalSysMock sys_mock;
1094d1c687eSPatrick Venture     std::unique_ptr<PpcMemDevice> devmem;
1104d1c687eSPatrick Venture };
1114d1c687eSPatrick Venture 
TEST_F(PpcMemTest,OpenFromReadFails)1124d1c687eSPatrick Venture TEST_F(PpcMemTest, OpenFromReadFails)
1134d1c687eSPatrick Venture {
1144d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1));
1154d1c687eSPatrick Venture 
1164d1c687eSPatrick Venture     char destination = 'b';
1174d1c687eSPatrick Venture     EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
1184d1c687eSPatrick Venture }
1194d1c687eSPatrick Venture 
TEST_F(PpcMemTest,PreadFails)1204d1c687eSPatrick Venture TEST_F(PpcMemTest, PreadFails)
1214d1c687eSPatrick Venture {
1224d1c687eSPatrick Venture     int fd = 1;
1234d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
1244d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(-1));
1254d1c687eSPatrick Venture 
1264d1c687eSPatrick Venture     char destination = 'b';
1274d1c687eSPatrick Venture     EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
1284d1c687eSPatrick Venture }
1294d1c687eSPatrick Venture 
TEST_F(PpcMemTest,PreadReadWorks)1304d1c687eSPatrick Venture TEST_F(PpcMemTest, PreadReadWorks)
1314d1c687eSPatrick Venture {
1324d1c687eSPatrick Venture     int fd = 1;
1334d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
1344d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(0));
1354d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, close(fd));
1364d1c687eSPatrick Venture 
1374d1c687eSPatrick Venture     /* Test does not validate byte is copied because that's part of pread and
1384d1c687eSPatrick Venture      * not the code.
1394d1c687eSPatrick Venture      */
1404d1c687eSPatrick Venture     char destination = 'b';
1414d1c687eSPatrick Venture     EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination));
1424d1c687eSPatrick Venture }
1434d1c687eSPatrick Venture 
TEST_F(PpcMemTest,OpenFromWriteFails)1444d1c687eSPatrick Venture TEST_F(PpcMemTest, OpenFromWriteFails)
1454d1c687eSPatrick Venture {
1464d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1));
1474d1c687eSPatrick Venture 
1484d1c687eSPatrick Venture     char source = 'a';
1494d1c687eSPatrick Venture     EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
1504d1c687eSPatrick Venture }
1514d1c687eSPatrick Venture 
TEST_F(PpcMemTest,PwriteFails)1524d1c687eSPatrick Venture TEST_F(PpcMemTest, PwriteFails)
1534d1c687eSPatrick Venture {
1544d1c687eSPatrick Venture     int fd = 1;
1554d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
1564d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(-1));
1574d1c687eSPatrick Venture 
1584d1c687eSPatrick Venture     char source = 'a';
1594d1c687eSPatrick Venture     EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
1604d1c687eSPatrick Venture }
1614d1c687eSPatrick Venture 
TEST_F(PpcMemTest,PwriteWorks)1624d1c687eSPatrick Venture TEST_F(PpcMemTest, PwriteWorks)
1634d1c687eSPatrick Venture {
1644d1c687eSPatrick Venture     int fd = 1;
1654d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd));
1664d1c687eSPatrick Venture     EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(0));
1674d1c687eSPatrick Venture 
1684d1c687eSPatrick Venture     /* Test does not validate byte is copied because that's part of pwrite and
1694d1c687eSPatrick Venture      * not the code.
1704d1c687eSPatrick Venture      */
1714d1c687eSPatrick Venture     char source = 'a';
1724d1c687eSPatrick Venture     EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source));
1734d1c687eSPatrick Venture }
1744d1c687eSPatrick Venture 
1754d1c687eSPatrick Venture } // namespace
1764d1c687eSPatrick Venture } // namespace host_tool
177