#include "internal_sys_mock.hpp" #include "io.hpp" #include #include #include #include namespace host_tool { namespace { using ::testing::_; using ::testing::Eq; using ::testing::Return; using ::testing::StrEq; class DevMemTest : public ::testing::Test { protected: DevMemTest() : devmem(std::make_unique(&sys_mock)) {} internal::InternalSysMock sys_mock; std::unique_ptr devmem; }; TEST_F(DevMemTest, OpenFromReadFails) { EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1)); char destination; EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); } TEST_F(DevMemTest, MmapFromReadFails) { int fd = 1; EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096)); EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED)); EXPECT_CALL(sys_mock, close(fd)); char destination; EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); } TEST_F(DevMemTest, CopiesOutOfMmap) { int fd = 1; char source = 'a'; EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096)); EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(&source)); EXPECT_CALL(sys_mock, munmap(_, _)); EXPECT_CALL(sys_mock, close(fd)); char destination = 'b'; EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); EXPECT_THAT(destination, Eq('a')); } TEST_F(DevMemTest, OpenFromWriteFails) { EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(-1)); char source; EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); } TEST_F(DevMemTest, MmapFromWriteFails) { int fd = 1; EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096)); EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)).WillOnce(Return(MAP_FAILED)); EXPECT_CALL(sys_mock, close(fd)); char source; EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); } TEST_F(DevMemTest, CopiesIntoMmap) { int fd = 1; char destination = 'b'; EXPECT_CALL(sys_mock, open(_, _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, getpagesize()).WillOnce(Return(4096)); EXPECT_CALL(sys_mock, mmap(0, _, _, _, fd, _)) .WillOnce(Return(&destination)); EXPECT_CALL(sys_mock, munmap(_, _)); EXPECT_CALL(sys_mock, close(fd)); char source = 'a'; EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); EXPECT_THAT(destination, Eq('a')); } class PpcMemTest : public ::testing::Test { protected: static constexpr char path[] = "/dev/fun"; PpcMemTest() : devmem(std::make_unique(path, &sys_mock)) {} internal::InternalSysMock sys_mock; std::unique_ptr devmem; }; TEST_F(PpcMemTest, OpenFromReadFails) { EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1)); char destination = 'b'; EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); } TEST_F(PpcMemTest, PreadFails) { int fd = 1; EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(-1)); char destination = 'b'; EXPECT_FALSE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); } TEST_F(PpcMemTest, PreadReadWorks) { int fd = 1; EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, pread(fd, _, 1, 0)).WillOnce(Return(0)); EXPECT_CALL(sys_mock, close(fd)); /* Test does not validate byte is copied because that's part of pread and * not the code. */ char destination = 'b'; EXPECT_TRUE(devmem->read(/*offset*/ 0, /*length*/ 1, &destination)); } TEST_F(PpcMemTest, OpenFromWriteFails) { EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(-1)); char source = 'a'; EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); } TEST_F(PpcMemTest, PwriteFails) { int fd = 1; EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(-1)); char source = 'a'; EXPECT_FALSE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); } TEST_F(PpcMemTest, PwriteWorks) { int fd = 1; EXPECT_CALL(sys_mock, open(StrEq(path), _)).WillOnce(Return(fd)); EXPECT_CALL(sys_mock, pwrite(fd, _, 1, 0)).WillOnce(Return(0)); /* Test does not validate byte is copied because that's part of pwrite and * not the code. */ char source = 'a'; EXPECT_TRUE(devmem->write(/*offset*/ 0, /*length*/ 1, &source)); } } // namespace } // namespace host_tool