Fixed errno handling of fuse test cases

This commit is contained in:
Sebastian Messmer 2014-12-06 15:33:01 +01:00
parent b652daec94
commit c298457209
55 changed files with 296 additions and 179 deletions

View File

@ -21,7 +21,6 @@ TEST_P(FuseAccessErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, access(StrEq(FILENAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = AccessFileAllowError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = AccessFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), error);
}

View File

@ -1,13 +1,18 @@
#include "FuseAccessTest.h"
void FuseAccessTest::AccessFile(const char *filename, int mode) {
int retval = AccessFileAllowError(filename, mode);
EXPECT_EQ(0, retval);
int error = AccessFileReturnError(filename, mode);
EXPECT_EQ(0, error);
}
int FuseAccessTest::AccessFileAllowError(const char *filename, int mode) {
int FuseAccessTest::AccessFileReturnError(const char *filename, int mode) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
return ::access(realpath.c_str(), mode);
int retval = ::access(realpath.c_str(), mode);
if (retval == 0) {
return 0;
} else {
return errno;
}
}

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void AccessFile(const char *filename, int mode);
int AccessFileAllowError(const char *filename, int mode);
int AccessFileReturnError(const char *filename, int mode);
};
#endif

View File

@ -21,17 +21,14 @@ TEST_F(FuseCreateAndOpenErrorTest, ReturnNoError) {
//For the syscall to succeed, we also need to give an fstat implementation.
ReturnIsFileOnFstat(1);
errno = 0;
int retval = CreateAndOpenFileAllowError(FILENAME, O_RDONLY);
EXPECT_EQ(errno, 0);
EXPECT_GE(retval, 0);
int error = CreateAndOpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(0, error);
}
TEST_P(FuseCreateAndOpenErrorTest, ReturnError) {
ReturnDoesntExistOnLstat(FILENAME);
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = CreateAndOpenFileAllowError(FILENAME, O_RDONLY);
EXPECT_EQ(retval, -1);
EXPECT_EQ(GetParam(), errno);
int error = CreateAndOpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(GetParam(), error);
}

View File

@ -8,9 +8,23 @@ int FuseCreateAndOpenTest::CreateAndOpenFile(const char *filename, int flags) {
return fd;
}
int FuseCreateAndOpenTest::CreateAndOpenFileReturnError(const char *filename, int flags) {
int fd = CreateAndOpenFileAllowError(filename, flags);
if (fd >= 0) {
return 0;
} else {
return -fd;
}
}
int FuseCreateAndOpenTest::CreateAndOpenFileAllowError(const char *filename, int flags) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
return ::open(realpath.c_str(), flags | O_CREAT);
int fd = ::open(realpath.c_str(), flags | O_CREAT);
if (fd >= 0) {
return fd;
} else {
return -errno;
}
}

View File

@ -9,6 +9,8 @@ public:
const char *FILENAME = "/myfile";
int CreateAndOpenFile(const char *FILENAME, int flags);
int CreateAndOpenFileReturnError(const char *FILENAME, int flags);
private:
int CreateAndOpenFileAllowError(const char *FILENAME, int flags);
};

View File

@ -22,7 +22,6 @@ TEST_P(FuseFdatasyncErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, fdatasync(0))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = FdatasyncFileAllowError(FILENAME);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = FdatasyncFileReturnError(FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -1,15 +1,20 @@
#include "FuseFdatasyncTest.h"
void FuseFdatasyncTest::FdatasyncFile(const char *filename) {
int retval = FdatasyncFileAllowError(filename);
EXPECT_EQ(0, retval);
int error = FdatasyncFileReturnError(filename);
EXPECT_EQ(0, error);
}
int FuseFdatasyncTest::FdatasyncFileAllowError(const char *filename) {
int FuseFdatasyncTest::FdatasyncFileReturnError(const char *filename) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
return ::fdatasync(fd);
int retval = ::fdatasync(fd);
if (retval == 0) {
return 0;
} else {
return errno;
}
}
int FuseFdatasyncTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void FdatasyncFile(const char *filename);
int FdatasyncFileAllowError(const char *filename);
int FdatasyncFileReturnError(const char *filename);
private:
int OpenFile(const TempTestFS *fs, const char *filename);

View File

@ -27,6 +27,6 @@ TEST_P(FuseFlushErrorTest, ReturnErrorFromFlush) {
int fd = OpenFile(fs.get(), FILENAME);
int close_result = ::close(fd);
EXPECT_EQ(-1, close_result);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, close_result);
}

View File

@ -0,0 +1,19 @@
#include "FuseFlushTest.h"
void FuseFlushTest::OpenAndCloseFile(const std::string &filename) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
CloseFile(fd);
}
int FuseFlushTest::OpenFile(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / filename;
int fd = ::open(real_path.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Opening file failed";
return fd;
}
void FuseFlushTest::CloseFile(int fd) {
int retval = ::close(fd);
EXPECT_EQ(0, retval);
}

View File

@ -11,23 +11,9 @@ class FuseFlushTest: public FuseTest {
public:
const std::string FILENAME = "/myfile";
void OpenAndCloseFile(const std::string &filename) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
CloseFile(fd);
}
int OpenFile(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / filename;
int fd = ::open(real_path.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Opening file failed";
return fd;
}
void CloseFile(int fd) {
int retval = ::close(fd);
EXPECT_EQ(0, retval);
}
void OpenAndCloseFile(const std::string &filename);
int OpenFile(const TempTestFS *fs, const std::string &filename);
void CloseFile(int fd);
};

View File

@ -34,7 +34,6 @@ TEST_P(FuseFstatErrorTest, ReturnedErrorCodeIsCorrect) {
auto fs = TestFS();
int fd = CreateFileAllowErrors(fs.get(), FILENAME);
EXPECT_EQ(-1, fd);
EXPECT_EQ(GetParam(), errno);
int error = CreateFileReturnError(fs.get(), FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -10,9 +10,23 @@ int FuseFstatTest::CreateFile(const TempTestFS *fs, const std::string &filename)
return fd;
}
int FuseFstatTest::CreateFileReturnError(const TempTestFS *fs, const std::string &filename) {
int fd = CreateFileAllowErrors(fs, filename);
if (fd >= 0) {
return 0;
} else {
return -fd;
}
}
int FuseFstatTest::CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / filename;
return ::open(real_path.c_str(), O_RDWR | O_CREAT);
int fd = ::open(real_path.c_str(), O_RDWR | O_CREAT);
if (fd >= 0) {
return fd;
} else {
return -errno;
}
}
void FuseFstatTest::OnCreateAndOpenReturnFileDescriptor(const char *filename, int descriptor) {

View File

@ -7,8 +7,10 @@
class FuseFstatTest: public FuseTest {
public:
int CreateFile(const TempTestFS *fs, const std::string &filename);
int CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename);
int CreateFileReturnError(const TempTestFS *fs, const std::string &filename);
void OnCreateAndOpenReturnFileDescriptor(const char *filename, int descriptor);
private:
int CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename);
};

View File

@ -22,7 +22,6 @@ TEST_P(FuseFsyncErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, fsync(0))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = FsyncFileAllowError(FILENAME);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = FsyncFileReturnError(FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -1,15 +1,20 @@
#include "FuseFsyncTest.h"
void FuseFsyncTest::FsyncFile(const char *filename) {
int retval = FsyncFileAllowError(filename);
EXPECT_EQ(0, retval);
int error = FsyncFileReturnError(filename);
EXPECT_EQ(0, error);
}
int FuseFsyncTest::FsyncFileAllowError(const char *filename) {
int FuseFsyncTest::FsyncFileReturnError(const char *filename) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
return ::fsync(fd);
int retval = ::fsync(fd);
if (retval == 0) {
return 0;
} else {
return errno;
}
}
int FuseFsyncTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void FsyncFile(const char *filename);
int FsyncFileAllowError(const char *filename);
int FsyncFileReturnError(const char *filename);
private:
int OpenFile(const TempTestFS *fs, const char *filename);

View File

@ -24,7 +24,6 @@ TEST_P(FuseFTruncateErrorTest, ReturnedErrorIsCorrect) {
//Needed to make ::ftruncate system call return successfully
ReturnIsFileOnFstat(0);
int retval = FTruncateFileAllowError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = FTruncateFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), error);
}

View File

@ -1,15 +1,20 @@
#include "FuseFTruncateTest.h"
void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) {
int retval = FTruncateFileAllowError(filename, size);
EXPECT_EQ(0, retval);
int error = FTruncateFileReturnError(filename, size);
EXPECT_EQ(0, error);
}
int FuseFTruncateTest::FTruncateFileAllowError(const char *filename, off_t size) {
int FuseFTruncateTest::FTruncateFileReturnError(const char *filename, off_t size) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
return ::ftruncate(fd, size);
int retval = ::ftruncate(fd, size);
if (0 == retval) {
return 0;
} else {
return errno;
}
}
int FuseFTruncateTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void FTruncateFile(const char *filename, off_t size);
int FTruncateFileAllowError(const char *filename, off_t size);
int FTruncateFileReturnError(const char *filename, off_t size);
private:
int OpenFile(const TempTestFS *fs, const char *filename);

View File

@ -18,14 +18,12 @@ INSTANTIATE_TEST_CASE_P(LstatErrorCodes, FuseLstatErrorTest, Values(EACCES, EBAD
TEST_F(FuseLstatErrorTest, ReturnNoError) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(ReturnIsFile);
errno = 0;
int retval = LstatPathAllowErrors(FILENAME);
EXPECT_EQ(errno, 0);
EXPECT_EQ(retval, 0);
int error = LstatPathReturnError(FILENAME);
EXPECT_EQ(0, error);
}
TEST_P(FuseLstatErrorTest, ReturnError) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = LstatPathAllowErrors(FILENAME);
EXPECT_EQ(retval, -1);
EXPECT_EQ(GetParam(), errno);
int error = LstatPathReturnError(FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -10,21 +10,26 @@ void FuseLstatTest::LstatPath(const std::string &path) {
LstatPath(path, &dummy);
}
int FuseLstatTest::LstatPathAllowErrors(const std::string &path) {
int FuseLstatTest::LstatPathReturnError(const std::string &path) {
struct stat dummy;
return LstatPathAllowErrors(path, &dummy);
return LstatPathReturnError(path, &dummy);
}
void FuseLstatTest::LstatPath(const std::string &path, struct stat *result) {
int retval = LstatPathAllowErrors(path, result);
EXPECT_EQ(0, retval) << "lstat syscall failed. errno: " << errno;
int error = LstatPathReturnError(path, result);
EXPECT_EQ(0, error) << "lstat syscall failed. errno: " << error;
}
int FuseLstatTest::LstatPathAllowErrors(const std::string &path, struct stat *result) {
int FuseLstatTest::LstatPathReturnError(const std::string &path, struct stat *result) {
auto fs = TestFS();
auto realpath = fs->mountDir() / path;
return ::lstat(realpath.c_str(), result);
int retval = ::lstat(realpath.c_str(), result);
if (retval == 0) {
return 0;
} else {
return errno;
}
}
struct stat FuseLstatTest::CallFileLstatWithImpl(function<void(struct stat*)> implementation) {

View File

@ -22,9 +22,9 @@ protected:
void LstatPath(const std::string &path, struct stat *result);
// These two functions are the same as LstatPath above, but they don't fail the test when the lstat syscall
// crashes. Instead, they return the result value of the lstat syscall.
int LstatPathAllowErrors(const std::string &path);
int LstatPathAllowErrors(const std::string &path, struct stat *result);
// crashes. Instead, they return the value of errno after calling ::lstat.
int LstatPathReturnError(const std::string &path);
int LstatPathReturnError(const std::string &path, struct stat *result);
// You can specify an implementation, which can modify the (struct stat *) result,
// our fuse mock filesystem implementation will then return this to fuse on an lstat call.

View File

@ -16,12 +16,20 @@ class FuseMkdirErrorTest: public FuseMkdirTest, public WithParamInterface<int> {
};
INSTANTIATE_TEST_CASE_P(FuseMkdirErrorTest, FuseMkdirErrorTest, Values(EACCES, EDQUOT, EEXIST, EFAULT, ELOOP, EMLINK, ENAMETOOLONG, ENOENT, ENOMEM, ENOSPC, ENOTDIR, EPERM, EROFS, EBADF));
TEST_F(FuseMkdirErrorTest, NoError) {
ReturnDoesntExistOnLstat(DIRNAME);
EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), _))
.Times(1).WillOnce(FromNowOnReturnIsDirOnLstat());
int error = MkdirReturnError(DIRNAME, 0);
EXPECT_EQ(0, error);
}
TEST_P(FuseMkdirErrorTest, ReturnedErrorIsCorrect) {
ReturnDoesntExistOnLstat(DIRNAME);
EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = MkdirAllowError(DIRNAME, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = MkdirReturnError(DIRNAME, 0);
EXPECT_EQ(GetParam(), error);
}

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke;
void FuseMkdirTest::Mkdir(const char *dirname, mode_t mode) {
int retval = MkdirAllowError(dirname, mode);
EXPECT_EQ(0, retval);
int error = MkdirReturnError(dirname, mode);
EXPECT_EQ(0, error);
}
int FuseMkdirTest::MkdirAllowError(const char *dirname, mode_t mode) {
int FuseMkdirTest::MkdirReturnError(const char *dirname, mode_t mode) {
auto fs = TestFS();
auto realpath = fs->mountDir() / dirname;
return ::mkdir(realpath.c_str(), mode);
int retval = ::mkdir(realpath.c_str(), mode);
if (retval == 0) {
return 0;
} else {
return errno;
}
}
Action<void(const char*, mode_t)> FuseMkdirTest::FromNowOnReturnIsDirOnLstat() {

View File

@ -9,7 +9,7 @@ public:
const char *DIRNAME = "/mydir";
void Mkdir(const char *dirname, mode_t mode);
int MkdirAllowError(const char *dirname, mode_t mode);
int MkdirReturnError(const char *dirname, mode_t mode);
::testing::Action<void(const char*, mode_t)> FromNowOnReturnIsDirOnLstat();
};

View File

@ -13,21 +13,19 @@ using namespace fspp::fuse;
class FuseOpenErrorTest: public FuseOpenTest, public WithParamInterface<int> {
};
INSTANTIATE_TEST_CASE_P(OpenErrorCodes, FuseOpenErrorTest, Values(EACCES, EDQUOT, EEXIST, EFAULT, EFBIG, EINTR, EOVERFLOW, EINVAL, EISDIR, ELOOP, EMFILE, ENAMETOOLONG, ENFILE, ENODEV, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENXIO, EOPNOTSUPP, EPERM, EROFS, ETXTBSY, EWOULDBLOCK, EBADF, ENOTDIR));
INSTANTIATE_TEST_CASE_P(FuseOpenErrorTest, FuseOpenErrorTest, Values(EACCES, EDQUOT, EEXIST, EFAULT, EFBIG, EINTR, EOVERFLOW, EINVAL, EISDIR, ELOOP, EMFILE, ENAMETOOLONG, ENFILE, ENODEV, ENOENT, ENOMEM, ENOSPC, ENOTDIR, ENXIO, EOPNOTSUPP, EPERM, EROFS, ETXTBSY, EWOULDBLOCK, EBADF, ENOTDIR));
TEST_F(FuseOpenErrorTest, ReturnNoError) {
ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Return(1));
errno = 0;
int retval = OpenFileAllowError(FILENAME, O_RDONLY);
EXPECT_EQ(errno, 0);
EXPECT_GE(retval, 0);
int error = OpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(0, error);
}
TEST_P(FuseOpenErrorTest, ReturnError) {
ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = OpenFileAllowError(FILENAME, O_RDONLY);
EXPECT_EQ(retval, -1);
EXPECT_EQ(GetParam(), errno);
int error = OpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(GetParam(), error);
}

View File

@ -6,9 +6,23 @@ int FuseOpenTest::OpenFile(const char *filename, int flags) {
return fd;
}
int FuseOpenTest::OpenFileReturnError(const char *filename, int flags) {
int fd = OpenFileAllowError(filename, flags);
if (fd >= 0) {
return 0;
} else {
return -fd;
}
}
int FuseOpenTest::OpenFileAllowError(const char *filename, int flags) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
return ::open(realpath.c_str(), flags);
int fd = ::open(realpath.c_str(), flags);
if (fd >= 0) {
return fd;
} else {
return -errno;
}
}

View File

@ -9,6 +9,8 @@ public:
const char *FILENAME = "/myfile";
int OpenFile(const char *FILENAME, int flags);
int OpenFileReturnError(const char *FILENAME, int flags);
private:
int OpenFileAllowError(const char *FILENAME, int flags);
};

View File

@ -33,10 +33,8 @@ TEST_P(FuseReadErrorTest, ReturnErrorOnFirstReadCall) {
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[READCOUNT];
errno = 0;
int retval = ReadFileAllowError(FILENAME, buf, READCOUNT, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
auto retval = ReadFileReturnError(FILENAME, buf, READCOUNT, 0);
EXPECT_EQ(GetParam(), retval.error);
delete[] buf;
}
@ -56,9 +54,8 @@ TEST_P(FuseReadErrorTest, ReturnErrorOnSecondReadCall) {
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[READCOUNT];
errno = 0;
size_t retval = ReadFileAllowError(FILENAME, buf, READCOUNT, 0);
EXPECT_EQ(0, errno);
EXPECT_EQ(successfullyReadBytes, retval); // Check that we're getting the number of successfully read bytes (the first read call) returned
auto retval = ReadFileReturnError(FILENAME, buf, READCOUNT, 0);
EXPECT_EQ(0, retval.error);
EXPECT_EQ(successfullyReadBytes, retval.read_bytes); // Check that we're getting the number of successfully read bytes (the first read call) returned
delete[] buf;
}

View File

@ -29,12 +29,12 @@ public:
TEST_F(FuseReadOverflowTest, ReadMoreThanFileSizeFromBeginning) {
char buf[READSIZE];
size_t read_bytes = ReadFileAllowError(FILENAME, buf, READSIZE, 0);
EXPECT_EQ(FILESIZE, read_bytes);
auto retval = ReadFileReturnError(FILENAME, buf, READSIZE, 0);
EXPECT_EQ(FILESIZE, retval.read_bytes);
}
TEST_F(FuseReadOverflowTest, ReadMoreThanFileSizeFromMiddle) {
char buf[READSIZE];
size_t read_bytes = ReadFileAllowError(FILENAME, buf, READSIZE, OFFSET);
EXPECT_EQ(FILESIZE-OFFSET, read_bytes);
auto retval = ReadFileReturnError(FILENAME, buf, READSIZE, OFFSET);
EXPECT_EQ(FILESIZE-OFFSET, retval.read_bytes);
}

View File

@ -1,15 +1,21 @@
#include "FuseReadTest.h"
void FuseReadTest::ReadFile(const char *filename, void *buf, size_t count, off_t offset) {
size_t retval = ReadFileAllowError(filename, buf, count, offset);
EXPECT_EQ(count, retval);
auto retval = ReadFileReturnError(filename, buf, count, offset);
EXPECT_EQ(0, retval.error);
EXPECT_EQ(count, retval.read_bytes);
}
size_t FuseReadTest::ReadFileAllowError(const char *filename, void *buf, size_t count, off_t offset) {
FuseReadTest::ReadError FuseReadTest::ReadFileReturnError(const char *filename, void *buf, size_t count, off_t offset) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
return ::pread(fd, buf, count, offset);
ReadError result;
errno = 0;
result.read_bytes = ::pread(fd, buf, count, offset);
result.error = errno;
return result;
}
int FuseReadTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -8,8 +8,13 @@ class FuseReadTest: public FuseTest {
public:
const char *FILENAME = "/myfile";
struct ReadError {
int error;
size_t read_bytes;
};
void ReadFile(const char *filename, void *buf, size_t count, off_t offset);
size_t ReadFileAllowError(const char *filename, void *buf, size_t count, off_t offset);
ReadError ReadFileReturnError(const char *filename, void *buf, size_t count, off_t offset);
::testing::Action<int(int, void*, size_t, off_t)> ReturnSuccessfulRead =
::testing::Invoke([](int, void *, size_t count, off_t) {

View File

@ -22,7 +22,6 @@ TEST_P(FuseRenameErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, rename(StrEq(FILENAME1), StrEq(FILENAME2)))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = RenameAllowError(FILENAME1, FILENAME2);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = RenameReturnError(FILENAME1, FILENAME2);
EXPECT_EQ(GetParam(), error);
}

View File

@ -4,14 +4,19 @@ using ::testing::Action;
using ::testing::Invoke;
void FuseRenameTest::Rename(const char *from, const char *to) {
int retval = RenameAllowError(from, to);
EXPECT_EQ(0, retval);
int error = RenameReturnError(from, to);
EXPECT_EQ(0, error);
}
int FuseRenameTest::RenameAllowError(const char *from, const char *to) {
int FuseRenameTest::RenameReturnError(const char *from, const char *to) {
auto fs = TestFS();
auto realfrom = fs->mountDir() / from;
auto realto = fs->mountDir() / to;
return ::rename(realfrom.c_str(), realto.c_str());
int retval = ::rename(realfrom.c_str(), realto.c_str());
if (0 == retval) {
return 0;
} else {
return errno;
}
}

View File

@ -10,7 +10,7 @@ public:
const char *FILENAME2 = "/myfile2";
void Rename(const char *from, const char *to);
int RenameAllowError(const char *from, const char *to);
int RenameReturnError(const char *from, const char *to);
};
#endif

View File

@ -21,7 +21,6 @@ TEST_P(FuseRmdirErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, rmdir(StrEq(DIRNAME)))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = RmdirAllowError(DIRNAME);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = RmdirReturnError(DIRNAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke;
void FuseRmdirTest::Rmdir(const char *dirname) {
int retval = RmdirAllowError(dirname);
EXPECT_EQ(0, retval);
int error = RmdirReturnError(dirname);
EXPECT_EQ(0, error);
}
int FuseRmdirTest::RmdirAllowError(const char *dirname) {
int FuseRmdirTest::RmdirReturnError(const char *dirname) {
auto fs = TestFS();
auto realpath = fs->mountDir() / dirname;
return ::rmdir(realpath.c_str());
int retval = ::rmdir(realpath.c_str());
if (retval == 0) {
return 0;
} else {
return errno;
}
}
Action<void(const char*)> FuseRmdirTest::FromNowOnReturnDoesntExistOnLstat() {

View File

@ -9,7 +9,7 @@ public:
const char *DIRNAME = "/mydir";
void Rmdir(const char *dirname);
int RmdirAllowError(const char *dirname);
int RmdirReturnError(const char *dirname);
::testing::Action<void(const char*)> FromNowOnReturnDoesntExistOnLstat();
};

View File

@ -19,16 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseStatfsErrorTest, FuseStatfsErrorTest, Values(EACCES,
TEST_F(FuseStatfsErrorTest, ReturnNoError) {
ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, statfs(StrEq(FILENAME), _)).Times(1).WillOnce(Return());
errno = 0;
int retval = StatfsAllowErrors(FILENAME);
EXPECT_EQ(errno, 0);
EXPECT_EQ(retval, 0);
int error = StatfsReturnError(FILENAME);
EXPECT_EQ(0, error);
}
TEST_P(FuseStatfsErrorTest, ReturnError) {
ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, statfs(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = StatfsAllowErrors(FILENAME);
EXPECT_EQ(retval, -1);
EXPECT_EQ(GetParam(), errno);
int error = StatfsReturnError(FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -10,21 +10,26 @@ void FuseStatfsTest::Statfs(const std::string &path) {
Statfs(path, &dummy);
}
int FuseStatfsTest::StatfsAllowErrors(const std::string &path) {
int FuseStatfsTest::StatfsReturnError(const std::string &path) {
struct ::statvfs dummy;
return StatfsAllowErrors(path, &dummy);
return StatfsReturnError(path, &dummy);
}
void FuseStatfsTest::Statfs(const std::string &path, struct ::statvfs *result) {
int retval = StatfsAllowErrors(path, result);
EXPECT_EQ(0, retval) << "lstat syscall failed. errno: " << errno;
int error = StatfsReturnError(path, result);
EXPECT_EQ(0, error) << "lstat syscall failed. errno: " << errno;
}
int FuseStatfsTest::StatfsAllowErrors(const std::string &path, struct ::statvfs *result) {
int FuseStatfsTest::StatfsReturnError(const std::string &path, struct ::statvfs *result) {
auto fs = TestFS();
auto realpath = fs->mountDir() / path;
return ::statvfs(realpath.c_str(), result);
int retval = ::statvfs(realpath.c_str(), result);
if (retval == 0) {
return 0;
} else {
return errno;
}
}
struct ::statvfs FuseStatfsTest::CallStatfsWithImpl(function<void(struct ::statvfs*)> implementation) {

View File

@ -23,8 +23,8 @@ protected:
// These two functions are the same as Statfs above, but they don't fail the test when the statfs syscall
// crashes. Instead, they return the result value of the statfs syscall.
int StatfsAllowErrors(const std::string &path);
int StatfsAllowErrors(const std::string &path, struct ::statvfs *result);
int StatfsReturnError(const std::string &path);
int StatfsReturnError(const std::string &path, struct ::statvfs *result);
// You can specify an implementation, which can modify the (struct statfs *) result,
// our fuse mock filesystem implementation will then return this to fuse on an statfs call.

View File

@ -21,7 +21,6 @@ TEST_P(FuseTruncateErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, truncate(StrEq(FILENAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = TruncateFileAllowError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = TruncateFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), error);
}

View File

@ -1,13 +1,18 @@
#include "FuseTruncateTest.h"
void FuseTruncateTest::TruncateFile(const char *filename, off_t size) {
int retval = TruncateFileAllowError(filename, size);
EXPECT_EQ(0, retval);
int error = TruncateFileReturnError(filename, size);
EXPECT_EQ(0, error);
}
int FuseTruncateTest::TruncateFileAllowError(const char *filename, off_t size) {
int FuseTruncateTest::TruncateFileReturnError(const char *filename, off_t size) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
return ::truncate(realpath.c_str(), size);
int retval = ::truncate(realpath.c_str(), size);
if (retval == 0) {
return 0;
} else {
return errno;
}
}

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void TruncateFile(const char *filename, off_t size);
int TruncateFileAllowError(const char *filename, off_t size);
int TruncateFileReturnError(const char *filename, off_t size);
};
#endif

View File

@ -21,7 +21,6 @@ TEST_P(FuseUnlinkErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, unlink(StrEq(FILENAME)))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = UnlinkAllowError(FILENAME);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = UnlinkReturnError(FILENAME);
EXPECT_EQ(GetParam(), error);
}

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke;
void FuseUnlinkTest::Unlink(const char *filename) {
int retval = UnlinkAllowError(filename);
EXPECT_EQ(0, retval);
int error = UnlinkReturnError(filename);
EXPECT_EQ(0, error);
}
int FuseUnlinkTest::UnlinkAllowError(const char *filename) {
int FuseUnlinkTest::UnlinkReturnError(const char *filename) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
return ::unlink(realpath.c_str());
int retval = ::unlink(realpath.c_str());
if (0 == retval) {
return 0;
} else {
return errno;
}
}
Action<void(const char*)> FuseUnlinkTest::FromNowOnReturnDoesntExistOnLstat() {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile";
void Unlink(const char *filename);
int UnlinkAllowError(const char *filename);
int UnlinkReturnError(const char *filename);
::testing::Action<void(const char*)> FromNowOnReturnDoesntExistOnLstat();
};

View File

@ -21,7 +21,6 @@ TEST_P(FuseUtimensErrorTest, ReturnedErrorIsCorrect) {
EXPECT_CALL(fsimpl, utimens(StrEq(FILENAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = UtimensAllowError(FILENAME, TIMEVALUES);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
int error = UtimensReturnError(FILENAME, TIMEVALUES);
EXPECT_EQ(GetParam(), error);
}

View File

@ -4,11 +4,11 @@
#include <sys/time.h>
void FuseUtimensTest::Utimens(const char *filename, const timespec times[2]) {
int retval = UtimensAllowError(filename, times);
EXPECT_EQ(0, retval);
int error = UtimensReturnError(filename, times);
EXPECT_EQ(0, error);
}
int FuseUtimensTest::UtimensAllowError(const char *filename, const timespec times[2]) {
int FuseUtimensTest::UtimensReturnError(const char *filename, const timespec times[2]) {
auto fs = TestFS();
auto realpath = fs->mountDir() / filename;
@ -16,7 +16,12 @@ int FuseUtimensTest::UtimensAllowError(const char *filename, const timespec time
struct timeval casted_times[2];
TIMESPEC_TO_TIMEVAL(&casted_times[0], &times[0]);
TIMESPEC_TO_TIMEVAL(&casted_times[1], &times[1]);
return ::utimes(realpath.c_str(), casted_times);
int retval = ::utimes(realpath.c_str(), casted_times);
if (0 == retval) {
return 0;
} else {
return errno;
}
}
struct timespec FuseUtimensTest::makeTimespec(time_t tv_sec, long tv_nsec) {

View File

@ -10,7 +10,7 @@ public:
struct timespec TIMEVALUES[2] = {makeTimespec(0,0), makeTimespec(0,0)};
void Utimens(const char *filename, const timespec times[2]);
int UtimensAllowError(const char *filename, const timespec times[2]);
int UtimensReturnError(const char *filename, const timespec times[2]);
static struct timespec makeTimespec(time_t tv_sec, long tv_nsec);
};

View File

@ -33,10 +33,8 @@ TEST_P(FuseWriteErrorTest, ReturnErrorOnFirstWriteCall) {
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[WRITECOUNT];
errno = 0;
int retval = WriteFileAllowError(FILENAME, buf, WRITECOUNT, 0);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
auto retval = WriteFileReturnError(FILENAME, buf, WRITECOUNT, 0);
EXPECT_EQ(GetParam(), retval.error);
delete[] buf;
}
@ -55,10 +53,9 @@ TEST_P(FuseWriteErrorTest, ReturnErrorOnSecondWriteCall) {
.WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[WRITECOUNT];
errno = 0;
size_t retval = WriteFileAllowError(FILENAME, buf, WRITECOUNT, 0);
EXPECT_EQ(0, errno);
EXPECT_EQ(successfullyWrittenBytes, retval); // Check that we're getting the number of successfully written bytes (the first write call) returned
auto retval = WriteFileReturnError(FILENAME, buf, WRITECOUNT, 0);
EXPECT_EQ(0, retval.error);
EXPECT_EQ(successfullyWrittenBytes, retval.written_bytes); // Check that we're getting the number of successfully written bytes (the first write call) returned
delete[] buf;
}

View File

@ -1,15 +1,21 @@
#include "FuseWriteTest.h"
void FuseWriteTest::WriteFile(const char *filename, const void *buf, size_t count, off_t offset) {
size_t retval = WriteFileAllowError(filename, buf, count, offset);
EXPECT_EQ(count, retval);
auto retval = WriteFileReturnError(filename, buf, count, offset);
EXPECT_EQ(0, retval.error);
EXPECT_EQ(count, retval.written_bytes);
}
size_t FuseWriteTest::WriteFileAllowError(const char *filename, const void *buf, size_t count, off_t offset) {
FuseWriteTest::WriteError FuseWriteTest::WriteFileReturnError(const char *filename, const void *buf, size_t count, off_t offset) {
auto fs = TestFS();
int fd = OpenFile(fs.get(), filename);
return ::pwrite(fd, buf, count, offset);
WriteError result;
errno = 0;
result.written_bytes = ::pwrite(fd, buf, count, offset);
result.error = errno;
return result;
}
int FuseWriteTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -8,8 +8,13 @@ class FuseWriteTest: public FuseTest {
public:
const char *FILENAME = "/myfile";
struct WriteError {
int error;
size_t written_bytes;
};
void WriteFile(const char *filename, const void *buf, size_t count, off_t offset);
size_t WriteFileAllowError(const char *filename, const void *buf, size_t count, off_t offset);
WriteError WriteFileReturnError(const char *filename, const void *buf, size_t count, off_t offset);
private:
int OpenFile(const TempTestFS *fs, const char *filename);