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