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), _)) EXPECT_CALL(fsimpl, access(StrEq(FILENAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); .Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = AccessFileAllowError(FILENAME, 0); int error = AccessFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -1,13 +1,18 @@
#include "FuseAccessTest.h" #include "FuseAccessTest.h"
void FuseAccessTest::AccessFile(const char *filename, int mode) { void FuseAccessTest::AccessFile(const char *filename, int mode) {
int retval = AccessFileAllowError(filename, mode); int error = AccessFileReturnError(filename, mode);
EXPECT_EQ(0, retval); EXPECT_EQ(0, error);
} }
int FuseAccessTest::AccessFileAllowError(const char *filename, int mode) { int FuseAccessTest::AccessFileReturnError(const char *filename, int mode) {
auto fs = TestFS(); auto fs = TestFS();
auto realpath = fs->mountDir() / filename; 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"; const char *FILENAME = "/myfile";
void AccessFile(const char *filename, int mode); void AccessFile(const char *filename, int mode);
int AccessFileAllowError(const char *filename, int mode); int AccessFileReturnError(const char *filename, int mode);
}; };
#endif #endif

View File

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

View File

@ -8,9 +8,23 @@ int FuseCreateAndOpenTest::CreateAndOpenFile(const char *filename, int flags) {
return fd; 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) { int FuseCreateAndOpenTest::CreateAndOpenFileAllowError(const char *filename, int flags) {
auto fs = TestFS(); auto fs = TestFS();
auto realpath = fs->mountDir() / filename; 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"; const char *FILENAME = "/myfile";
int CreateAndOpenFile(const char *FILENAME, int flags); int CreateAndOpenFile(const char *FILENAME, int flags);
int CreateAndOpenFileReturnError(const char *FILENAME, int flags);
private:
int CreateAndOpenFileAllowError(const char *FILENAME, int flags); int CreateAndOpenFileAllowError(const char *FILENAME, int flags);
}; };

View File

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

View File

@ -1,15 +1,20 @@
#include "FuseFdatasyncTest.h" #include "FuseFdatasyncTest.h"
void FuseFdatasyncTest::FdatasyncFile(const char *filename) { void FuseFdatasyncTest::FdatasyncFile(const char *filename) {
int retval = FdatasyncFileAllowError(filename); int error = FdatasyncFileReturnError(filename);
EXPECT_EQ(0, retval); EXPECT_EQ(0, error);
} }
int FuseFdatasyncTest::FdatasyncFileAllowError(const char *filename) { int FuseFdatasyncTest::FdatasyncFileReturnError(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); 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) { int FuseFdatasyncTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile"; const char *FILENAME = "/myfile";
void FdatasyncFile(const char *filename); void FdatasyncFile(const char *filename);
int FdatasyncFileAllowError(const char *filename); int FdatasyncFileReturnError(const char *filename);
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); 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 fd = OpenFile(fs.get(), FILENAME);
int close_result = ::close(fd); int close_result = ::close(fd);
EXPECT_EQ(-1, close_result);
EXPECT_EQ(GetParam(), errno); 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: public:
const std::string FILENAME = "/myfile"; const std::string FILENAME = "/myfile";
void OpenAndCloseFile(const std::string &filename) { void OpenAndCloseFile(const std::string &filename);
auto fs = TestFS(); int OpenFile(const TempTestFS *fs, const std::string &filename);
int fd = OpenFile(fs.get(), filename); void CloseFile(int fd);
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);
}
}; };

View File

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

View File

@ -10,9 +10,23 @@ int FuseFstatTest::CreateFile(const TempTestFS *fs, const std::string &filename)
return fd; 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) { int FuseFstatTest::CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / 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) { void FuseFstatTest::OnCreateAndOpenReturnFileDescriptor(const char *filename, int descriptor) {

View File

@ -7,8 +7,10 @@
class FuseFstatTest: public FuseTest { class FuseFstatTest: public FuseTest {
public: public:
int CreateFile(const TempTestFS *fs, const std::string &filename); 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); 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)) EXPECT_CALL(fsimpl, fsync(0))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); .Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = FsyncFileAllowError(FILENAME); int error = FsyncFileReturnError(FILENAME);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -1,15 +1,20 @@
#include "FuseFsyncTest.h" #include "FuseFsyncTest.h"
void FuseFsyncTest::FsyncFile(const char *filename) { void FuseFsyncTest::FsyncFile(const char *filename) {
int retval = FsyncFileAllowError(filename); int error = FsyncFileReturnError(filename);
EXPECT_EQ(0, retval); EXPECT_EQ(0, error);
} }
int FuseFsyncTest::FsyncFileAllowError(const char *filename) { int FuseFsyncTest::FsyncFileReturnError(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); 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) { int FuseFsyncTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile"; const char *FILENAME = "/myfile";
void FsyncFile(const char *filename); void FsyncFile(const char *filename);
int FsyncFileAllowError(const char *filename); int FsyncFileReturnError(const char *filename);
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); 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 //Needed to make ::ftruncate system call return successfully
ReturnIsFileOnFstat(0); ReturnIsFileOnFstat(0);
int retval = FTruncateFileAllowError(FILENAME, 0); int error = FTruncateFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -1,15 +1,20 @@
#include "FuseFTruncateTest.h" #include "FuseFTruncateTest.h"
void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) { void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) {
int retval = FTruncateFileAllowError(filename, size); int error = FTruncateFileReturnError(filename, size);
EXPECT_EQ(0, retval); 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(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); 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) { int FuseFTruncateTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -9,7 +9,7 @@ public:
const char *FILENAME = "/myfile"; const char *FILENAME = "/myfile";
void FTruncateFile(const char *filename, off_t size); 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: private:
int OpenFile(const TempTestFS *fs, const char *filename); 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) { TEST_F(FuseLstatErrorTest, ReturnNoError) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(ReturnIsFile); EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(ReturnIsFile);
errno = 0; errno = 0;
int retval = LstatPathAllowErrors(FILENAME); int error = LstatPathReturnError(FILENAME);
EXPECT_EQ(errno, 0); EXPECT_EQ(0, error);
EXPECT_EQ(retval, 0);
} }
TEST_P(FuseLstatErrorTest, ReturnError) { TEST_P(FuseLstatErrorTest, ReturnError) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = LstatPathAllowErrors(FILENAME); int error = LstatPathReturnError(FILENAME);
EXPECT_EQ(retval, -1); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(GetParam(), errno);
} }

View File

@ -10,21 +10,26 @@ void FuseLstatTest::LstatPath(const std::string &path) {
LstatPath(path, &dummy); LstatPath(path, &dummy);
} }
int FuseLstatTest::LstatPathAllowErrors(const std::string &path) { int FuseLstatTest::LstatPathReturnError(const std::string &path) {
struct stat dummy; struct stat dummy;
return LstatPathAllowErrors(path, &dummy); return LstatPathReturnError(path, &dummy);
} }
void FuseLstatTest::LstatPath(const std::string &path, struct stat *result) { void FuseLstatTest::LstatPath(const std::string &path, struct stat *result) {
int retval = LstatPathAllowErrors(path, result); int error = LstatPathReturnError(path, result);
EXPECT_EQ(0, retval) << "lstat syscall failed. errno: " << errno; 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 fs = TestFS();
auto realpath = fs->mountDir() / path; 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) { 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); 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 // 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. // crashes. Instead, they return the value of errno after calling ::lstat.
int LstatPathAllowErrors(const std::string &path); int LstatPathReturnError(const std::string &path);
int LstatPathAllowErrors(const std::string &path, struct stat *result); int LstatPathReturnError(const std::string &path, struct stat *result);
// You can specify an implementation, which can modify the (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. // 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)); 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) { TEST_P(FuseMkdirErrorTest, ReturnedErrorIsCorrect) {
ReturnDoesntExistOnLstat(DIRNAME); ReturnDoesntExistOnLstat(DIRNAME);
EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), _)) EXPECT_CALL(fsimpl, mkdir(StrEq(DIRNAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); .Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = MkdirAllowError(DIRNAME, 0); int error = MkdirReturnError(DIRNAME, 0);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke; using ::testing::Invoke;
void FuseMkdirTest::Mkdir(const char *dirname, mode_t mode) { void FuseMkdirTest::Mkdir(const char *dirname, mode_t mode) {
int retval = MkdirAllowError(dirname, mode); int error = MkdirReturnError(dirname, mode);
EXPECT_EQ(0, retval); 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 fs = TestFS();
auto realpath = fs->mountDir() / dirname; 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() { Action<void(const char*, mode_t)> FuseMkdirTest::FromNowOnReturnIsDirOnLstat() {

View File

@ -9,7 +9,7 @@ public:
const char *DIRNAME = "/mydir"; const char *DIRNAME = "/mydir";
void Mkdir(const char *dirname, mode_t mode); 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(); ::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> { 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) { TEST_F(FuseOpenErrorTest, ReturnNoError) {
ReturnIsFileOnLstat(FILENAME); ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Return(1)); EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Return(1));
errno = 0; errno = 0;
int retval = OpenFileAllowError(FILENAME, O_RDONLY); int error = OpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(errno, 0); EXPECT_EQ(0, error);
EXPECT_GE(retval, 0);
} }
TEST_P(FuseOpenErrorTest, ReturnError) { TEST_P(FuseOpenErrorTest, ReturnError) {
ReturnIsFileOnLstat(FILENAME); ReturnIsFileOnLstat(FILENAME);
EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); EXPECT_CALL(fsimpl, openFile(StrEq(FILENAME), _)).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = OpenFileAllowError(FILENAME, O_RDONLY); int error = OpenFileReturnError(FILENAME, O_RDONLY);
EXPECT_EQ(retval, -1); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(GetParam(), errno);
} }

View File

@ -6,9 +6,23 @@ int FuseOpenTest::OpenFile(const char *filename, int flags) {
return fd; 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) { int FuseOpenTest::OpenFileAllowError(const char *filename, int flags) {
auto fs = TestFS(); auto fs = TestFS();
auto realpath = fs->mountDir() / filename; 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"; const char *FILENAME = "/myfile";
int OpenFile(const char *FILENAME, int flags); int OpenFile(const char *FILENAME, int flags);
int OpenFileReturnError(const char *FILENAME, int flags);
private:
int OpenFileAllowError(const char *FILENAME, int flags); int OpenFileAllowError(const char *FILENAME, int flags);
}; };

View File

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

View File

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

View File

@ -1,15 +1,21 @@
#include "FuseReadTest.h" #include "FuseReadTest.h"
void FuseReadTest::ReadFile(const char *filename, void *buf, size_t count, off_t offset) { void FuseReadTest::ReadFile(const char *filename, void *buf, size_t count, off_t offset) {
size_t retval = ReadFileAllowError(filename, buf, count, offset); auto retval = ReadFileReturnError(filename, buf, count, offset);
EXPECT_EQ(count, retval); 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(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); 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) { int FuseReadTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -8,8 +8,13 @@ class FuseReadTest: public FuseTest {
public: public:
const char *FILENAME = "/myfile"; 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); 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::Action<int(int, void*, size_t, off_t)> ReturnSuccessfulRead =
::testing::Invoke([](int, void *, size_t count, off_t) { ::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))) EXPECT_CALL(fsimpl, rename(StrEq(FILENAME1), StrEq(FILENAME2)))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); .Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = RenameAllowError(FILENAME1, FILENAME2); int error = RenameReturnError(FILENAME1, FILENAME2);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -4,14 +4,19 @@ using ::testing::Action;
using ::testing::Invoke; using ::testing::Invoke;
void FuseRenameTest::Rename(const char *from, const char *to) { void FuseRenameTest::Rename(const char *from, const char *to) {
int retval = RenameAllowError(from, to); int error = RenameReturnError(from, to);
EXPECT_EQ(0, retval); 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 fs = TestFS();
auto realfrom = fs->mountDir() / from; auto realfrom = fs->mountDir() / from;
auto realto = fs->mountDir() / to; 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"; const char *FILENAME2 = "/myfile2";
void Rename(const char *from, const char *to); 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 #endif

View File

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

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke; using ::testing::Invoke;
void FuseRmdirTest::Rmdir(const char *dirname) { void FuseRmdirTest::Rmdir(const char *dirname) {
int retval = RmdirAllowError(dirname); int error = RmdirReturnError(dirname);
EXPECT_EQ(0, retval); EXPECT_EQ(0, error);
} }
int FuseRmdirTest::RmdirAllowError(const char *dirname) { int FuseRmdirTest::RmdirReturnError(const char *dirname) {
auto fs = TestFS(); auto fs = TestFS();
auto realpath = fs->mountDir() / dirname; 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() { Action<void(const char*)> FuseRmdirTest::FromNowOnReturnDoesntExistOnLstat() {

View File

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

View File

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

View File

@ -10,21 +10,26 @@ void FuseStatfsTest::Statfs(const std::string &path) {
Statfs(path, &dummy); Statfs(path, &dummy);
} }
int FuseStatfsTest::StatfsAllowErrors(const std::string &path) { int FuseStatfsTest::StatfsReturnError(const std::string &path) {
struct ::statvfs dummy; struct ::statvfs dummy;
return StatfsAllowErrors(path, &dummy); return StatfsReturnError(path, &dummy);
} }
void FuseStatfsTest::Statfs(const std::string &path, struct ::statvfs *result) { void FuseStatfsTest::Statfs(const std::string &path, struct ::statvfs *result) {
int retval = StatfsAllowErrors(path, result); int error = StatfsReturnError(path, result);
EXPECT_EQ(0, retval) << "lstat syscall failed. errno: " << errno; 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 fs = TestFS();
auto realpath = fs->mountDir() / path; 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) { 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 // 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. // crashes. Instead, they return the result value of the statfs syscall.
int StatfsAllowErrors(const std::string &path); int StatfsReturnError(const std::string &path);
int StatfsAllowErrors(const std::string &path, struct ::statvfs *result); int StatfsReturnError(const std::string &path, struct ::statvfs *result);
// You can specify an implementation, which can modify the (struct statfs *) 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. // 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), _)) EXPECT_CALL(fsimpl, truncate(StrEq(FILENAME), _))
.Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); .Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
int retval = TruncateFileAllowError(FILENAME, 0); int error = TruncateFileReturnError(FILENAME, 0);
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), error);
EXPECT_EQ(-1, retval);
} }

View File

@ -1,13 +1,18 @@
#include "FuseTruncateTest.h" #include "FuseTruncateTest.h"
void FuseTruncateTest::TruncateFile(const char *filename, off_t size) { void FuseTruncateTest::TruncateFile(const char *filename, off_t size) {
int retval = TruncateFileAllowError(filename, size); int error = TruncateFileReturnError(filename, size);
EXPECT_EQ(0, retval); 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 fs = TestFS();
auto realpath = fs->mountDir() / filename; 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"; const char *FILENAME = "/myfile";
void TruncateFile(const char *filename, off_t size); 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 #endif

View File

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

View File

@ -4,15 +4,20 @@ using ::testing::Action;
using ::testing::Invoke; using ::testing::Invoke;
void FuseUnlinkTest::Unlink(const char *filename) { void FuseUnlinkTest::Unlink(const char *filename) {
int retval = UnlinkAllowError(filename); int error = UnlinkReturnError(filename);
EXPECT_EQ(0, retval); EXPECT_EQ(0, error);
} }
int FuseUnlinkTest::UnlinkAllowError(const char *filename) { int FuseUnlinkTest::UnlinkReturnError(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
auto realpath = fs->mountDir() / filename; 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() { Action<void(const char*)> FuseUnlinkTest::FromNowOnReturnDoesntExistOnLstat() {

View File

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

View File

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

View File

@ -4,11 +4,11 @@
#include <sys/time.h> #include <sys/time.h>
void FuseUtimensTest::Utimens(const char *filename, const timespec times[2]) { void FuseUtimensTest::Utimens(const char *filename, const timespec times[2]) {
int retval = UtimensAllowError(filename, times); int error = UtimensReturnError(filename, times);
EXPECT_EQ(0, retval); 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 fs = TestFS();
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
@ -16,7 +16,12 @@ int FuseUtimensTest::UtimensAllowError(const char *filename, const timespec time
struct timeval casted_times[2]; struct timeval casted_times[2];
TIMESPEC_TO_TIMEVAL(&casted_times[0], &times[0]); TIMESPEC_TO_TIMEVAL(&casted_times[0], &times[0]);
TIMESPEC_TO_TIMEVAL(&casted_times[1], &times[1]); 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) { 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)}; struct timespec TIMEVALUES[2] = {makeTimespec(0,0), makeTimespec(0,0)};
void Utimens(const char *filename, const timespec times[2]); 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); 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()))); .WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[WRITECOUNT]; char *buf = new char[WRITECOUNT];
errno = 0; auto retval = WriteFileReturnError(FILENAME, buf, WRITECOUNT, 0);
int retval = WriteFileAllowError(FILENAME, buf, WRITECOUNT, 0); EXPECT_EQ(GetParam(), retval.error);
EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, retval);
delete[] buf; delete[] buf;
} }
@ -55,10 +53,9 @@ TEST_P(FuseWriteErrorTest, ReturnErrorOnSecondWriteCall) {
.WillRepeatedly(Throw(FuseErrnoException(GetParam()))); .WillRepeatedly(Throw(FuseErrnoException(GetParam())));
char *buf = new char[WRITECOUNT]; char *buf = new char[WRITECOUNT];
errno = 0; auto retval = WriteFileReturnError(FILENAME, buf, WRITECOUNT, 0);
size_t retval = WriteFileAllowError(FILENAME, buf, WRITECOUNT, 0); EXPECT_EQ(0, retval.error);
EXPECT_EQ(0, errno); EXPECT_EQ(successfullyWrittenBytes, retval.written_bytes); // Check that we're getting the number of successfully written bytes (the first write call) returned
EXPECT_EQ(successfullyWrittenBytes, retval); // Check that we're getting the number of successfully written bytes (the first write call) returned
delete[] buf; delete[] buf;
} }

View File

@ -1,15 +1,21 @@
#include "FuseWriteTest.h" #include "FuseWriteTest.h"
void FuseWriteTest::WriteFile(const char *filename, const void *buf, size_t count, off_t offset) { void FuseWriteTest::WriteFile(const char *filename, const void *buf, size_t count, off_t offset) {
size_t retval = WriteFileAllowError(filename, buf, count, offset); auto retval = WriteFileReturnError(filename, buf, count, offset);
EXPECT_EQ(count, retval); 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(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); 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) { int FuseWriteTest::OpenFile(const TempTestFS *fs, const char *filename) {

View File

@ -8,8 +8,13 @@ class FuseWriteTest: public FuseTest {
public: public:
const char *FILENAME = "/myfile"; 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); 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: private:
int OpenFile(const TempTestFS *fs, const char *filename); int OpenFile(const TempTestFS *fs, const char *filename);