blob: 492c69983fcf9b58d10d082246459fd9b5af0af3 [file] [log] [blame]
#include "internal_sys_mock.hpp"
#include "io.hpp"
#include <sys/mman.h>
#include <memory>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
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<DevMemDevice>(&sys_mock))
{}
internal::InternalSysMock sys_mock;
std::unique_ptr<DevMemDevice> 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<PpcMemDevice>(path, &sys_mock))
{}
internal::InternalSysMock sys_mock;
std::unique_ptr<PpcMemDevice> 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