Fix some issues with fspp-test on Mac OS X

This commit is contained in:
Sebastian Messmer 2017-08-25 00:14:16 +01:00
parent f951f41877
commit bc46bc88e9
26 changed files with 184 additions and 125 deletions

View File

@ -100,7 +100,7 @@ set(SOURCES
fs_interface/DirTest.cpp fs_interface/DirTest.cpp
fs_interface/DeviceTest.cpp fs_interface/DeviceTest.cpp
fs_interface/OpenFileTest.cpp fs_interface/OpenFileTest.cpp
) testutils/OpenFileHandle.cpp testutils/OpenFileHandle.h)
add_executable(${PROJECT_NAME} ${SOURCES}) add_executable(${PROJECT_NAME} ${SOURCES})
target_link_libraries(${PROJECT_NAME} googletest fspp) target_link_libraries(${PROJECT_NAME} googletest fspp)

View File

@ -1,4 +1,5 @@
#include "../../testutils/FuseTest.h" #include "../../testutils/FuseTest.h"
#include "../../testutils/OpenFileHandle.h"
#include <condition_variable> #include <condition_variable>
using ::testing::_; using ::testing::_;
@ -17,6 +18,8 @@ using std::unique_lock;
using std::condition_variable; using std::condition_variable;
using std::chrono::duration; using std::chrono::duration;
using std::chrono::seconds; using std::chrono::seconds;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
// The fuse behaviour is: For each open(), there will be exactly one call to release(). // The fuse behaviour is: For each open(), there will be exactly one call to release().
// Directly before this call to release(), flush() will be called. After flush() returns, // Directly before this call to release(), flush() will be called. After flush() returns,
@ -58,20 +61,21 @@ public:
void OpenAndCloseFile(const string &filename) { void OpenAndCloseFile(const string &filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); auto fd = OpenFile(fs.get(), filename);
CloseFile(fd); CloseFile(std::move(fd));
} }
int OpenFile(const TempTestFS *fs, const string &filename) { unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const string &filename) {
auto real_path = fs->mountDir() / filename; auto real_path = fs->mountDir() / filename;
int fd = ::open(real_path.c_str(), O_RDONLY); auto fd = make_unique_ref<OpenFileHandle>(real_path.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Opening file failed"; EXPECT_GE(fd->fd(), 0) << "Opening file failed";
return fd; return fd;
} }
void CloseFile(int fd) { void CloseFile(unique_ref<OpenFileHandle> fd) {
int retval = ::close(fd); int retval = ::close(fd->fd());
EXPECT_EQ(0, retval); EXPECT_EQ(0, retval);
fd->release(); // don't try closing it again
} }
}; };
INSTANTIATE_TEST_CASE_P(FuseCloseTest, FuseCloseTest, Values(0, 1, 2, 100, 1024*1024*1024)); INSTANTIATE_TEST_CASE_P(FuseCloseTest, FuseCloseTest, Values(0, 1, 2, 100, 1024*1024*1024));

View File

@ -5,21 +5,23 @@ using ::testing::StrEq;
using ::testing::WithParamInterface; using ::testing::WithParamInterface;
using ::testing::Values; using ::testing::Values;
using ::testing::Return; using ::testing::Return;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
class FuseCreateAndOpenFileDescriptorTest: public FuseCreateAndOpenTest, public WithParamInterface<int> { class FuseCreateAndOpenFileDescriptorTest: public FuseCreateAndOpenTest, public WithParamInterface<int> {
public: public:
void CreateAndOpenAndReadFile(const char *filename) { void CreateAndOpenAndReadFile(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = CreateAndOpenFile(fs.get(), filename); auto fd = CreateAndOpenFile(fs.get(), filename);
ReadFile(fd); ReadFile(fd->fd());
} }
private: private:
int CreateAndOpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> CreateAndOpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDONLY | O_CREAT, S_IRUSR | S_IRGRP | S_IROTH);
EXPECT_GE(fd, 0) << "Creating file failed"; EXPECT_GE(fd->fd(), 0) << "Creating file failed";
return fd; return fd;
} }
void ReadFile(int fd) { void ReadFile(int fd) {

View File

@ -2,29 +2,16 @@
using ::testing::_; using ::testing::_;
int FuseCreateAndOpenTest::CreateAndOpenFile(const char *filename, int flags) { void FuseCreateAndOpenTest::CreateAndOpenFile(const char *filename, int flags) {
int fd = CreateAndOpenFileAllowError(filename, flags);
EXPECT_GE(fd, 0);
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 fs = TestFS();
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), flags | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); OpenFileHandle fd(realpath.c_str(), flags | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd >= 0) {
return fd; EXPECT_GE(fd.fd(), 0);
} else { }
return -errno;
} int FuseCreateAndOpenTest::CreateAndOpenFileReturnError(const char *filename, int flags) {
OpenFileHandle fd(filename, flags);
return fd.errorcode();
} }

View File

@ -3,15 +3,14 @@
#define MESSMER_FSPP_TEST_FUSE_CREATEANDOPENFILE_TESTUTILS_FUSECREATEANDOPENTEST_H_ #define MESSMER_FSPP_TEST_FUSE_CREATEANDOPENFILE_TESTUTILS_FUSECREATEANDOPENTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseCreateAndOpenTest: public FuseTest { class FuseCreateAndOpenTest: public FuseTest {
public: public:
const char *FILENAME = "/myfile"; const char *FILENAME = "/myfile";
int CreateAndOpenFile(const char *FILENAME, int flags); void CreateAndOpenFile(const char *FILENAME, int flags);
int CreateAndOpenFileReturnError(const char *FILENAME, int flags); int CreateAndOpenFileReturnError(const char *FILENAME, int flags);
private:
int CreateAndOpenFileAllowError(const char *FILENAME, int flags);
}; };
MATCHER_P(OpenFlagsEq, expectedFlags, "") { MATCHER_P(OpenFlagsEq, expectedFlags, "") {

View File

@ -1,6 +1,9 @@
#include "FuseFdatasyncTest.h" #include "FuseFdatasyncTest.h"
#include <fcntl.h> #include <fcntl.h>
using cpputils::unique_ref;
using cpputils::make_unique_ref;
void FuseFdatasyncTest::FdatasyncFile(const char *filename) { void FuseFdatasyncTest::FdatasyncFile(const char *filename) {
int error = FdatasyncFileReturnError(filename); int error = FdatasyncFileReturnError(filename);
EXPECT_EQ(0, error); EXPECT_EQ(0, error);
@ -9,10 +12,10 @@ void FuseFdatasyncTest::FdatasyncFile(const char *filename) {
int FuseFdatasyncTest::FdatasyncFileReturnError(const char *filename) { int FuseFdatasyncTest::FdatasyncFileReturnError(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); auto fd = OpenFile(fs.get(), filename);
#ifdef F_FULLFSYNC #ifdef F_FULLFSYNC
// This is MacOSX, which doesn't know fdatasync // This is MacOSX, which doesn't know fdatasync
int retval = fcntl(fd, F_FULLFSYNC); int retval = fcntl(fd->fd(), F_FULLFSYNC);
#else #else
int retval = ::fdatasync(fd); int retval = ::fdatasync(fd);
#endif #endif
@ -23,9 +26,9 @@ int FuseFdatasyncTest::FdatasyncFileReturnError(const char *filename) {
} }
} }
int FuseFdatasyncTest::OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> FuseFdatasyncTest::OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDWR); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDWR);
EXPECT_GE(fd, 0) << "Error opening file"; EXPECT_GE(fd->fd(), 0) << "Error opening file";
return fd; return fd;
} }

View File

@ -3,6 +3,7 @@
#define MESSMER_FSPP_TEST_FUSE_FDATASYNC_TESTUTILS_FUSEFDATASYNCTEST_H_ #define MESSMER_FSPP_TEST_FUSE_FDATASYNC_TESTUTILS_FUSEFDATASYNCTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseFdatasyncTest: public FuseTest { class FuseFdatasyncTest: public FuseTest {
public: public:
@ -12,7 +13,7 @@ public:
int FdatasyncFileReturnError(const char *filename); int FdatasyncFileReturnError(const char *filename);
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename);
}; };
#endif #endif

View File

@ -24,9 +24,10 @@ TEST_P(FuseFlushErrorTest, ReturnErrorFromFlush) {
EXPECT_CALL(fsimpl, flush(Eq(GetParam()))).Times(1).WillOnce(Throw(FuseErrnoException(GetParam()))); EXPECT_CALL(fsimpl, flush(Eq(GetParam()))).Times(1).WillOnce(Throw(FuseErrnoException(GetParam())));
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), FILENAME); auto fd = OpenFile(fs.get(), FILENAME);
int close_result = ::close(fd); int close_result = ::close(fd->fd());
EXPECT_EQ(GetParam(), errno); EXPECT_EQ(GetParam(), errno);
EXPECT_EQ(-1, close_result); EXPECT_EQ(-1, close_result);
fd->release(); // don't close it again
} }

View File

@ -1,15 +1,19 @@
#include "FuseFlushTest.h" #include "FuseFlushTest.h"
using cpputils::unique_ref;
using cpputils::make_unique_ref;
void FuseFlushTest::OpenAndCloseFile(const std::string &filename) { void FuseFlushTest::OpenAndCloseFile(const std::string &filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); auto fd = OpenFile(fs.get(), filename);
CloseFile(fd); CloseFile(fd->fd());
fd->release(); // don't try to close it again
} }
int FuseFlushTest::OpenFile(const TempTestFS *fs, const std::string &filename) { unique_ref<OpenFileHandle> FuseFlushTest::OpenFile(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / filename; auto real_path = fs->mountDir() / filename;
int fd = ::open(real_path.c_str(), O_RDONLY); auto fd = make_unique_ref<OpenFileHandle>(real_path.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Opening file failed"; EXPECT_GE(fd->fd(), 0) << "Opening file failed";
return fd; return fd;
} }

View File

@ -3,13 +3,14 @@
#define MESSMER_FSPP_TEST_FUSE_FLUSH_TESTUTILS_FUSEFLUSHTEST_H_ #define MESSMER_FSPP_TEST_FUSE_FLUSH_TESTUTILS_FUSEFLUSHTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseFlushTest: public FuseTest { 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);
int OpenFile(const TempTestFS *fs, const std::string &filename); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const std::string &filename);
void CloseFile(int fd); void CloseFile(int fd);
}; };

View File

@ -10,6 +10,9 @@ using ::testing::Eq;
using ::testing::Return; using ::testing::Return;
using ::testing::Throw; using ::testing::Throw;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
using namespace fspp::fuse; using namespace fspp::fuse;
// Cite from FUSE documentation on the fgetattr function: // Cite from FUSE documentation on the fgetattr function:
@ -19,10 +22,10 @@ using namespace fspp::fuse;
class FuseFstatErrorTest: public FuseFstatTest, public WithParamInterface<int> { class FuseFstatErrorTest: public FuseFstatTest, public WithParamInterface<int> {
public: public:
int CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename) { /*unique_ref<OpenFileHandle> 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, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); return make_unique_ref<OpenFileHandle>(real_path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
} }*/
}; };
INSTANTIATE_TEST_CASE_P(FuseFstatErrorTest, FuseFstatErrorTest, Values(EACCES, EBADF, EFAULT, ELOOP, ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EOVERFLOW)); INSTANTIATE_TEST_CASE_P(FuseFstatErrorTest, FuseFstatErrorTest, Values(EACCES, EBADF, EFAULT, ELOOP, ENAMETOOLONG, ENOENT, ENOMEM, ENOTDIR, EOVERFLOW));

View File

@ -3,30 +3,25 @@
using ::testing::StrEq; using ::testing::StrEq;
using ::testing::_; using ::testing::_;
using ::testing::Return; using ::testing::Return;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
int FuseFstatTest::CreateFile(const TempTestFS *fs, const std::string &filename) {
int fd = CreateFileAllowErrors(fs, filename); unique_ref<OpenFileHandle> FuseFstatTest::CreateFile(const TempTestFS *fs, const std::string &filename) {
EXPECT_GE(fd, 0) << "Opening file failed"; auto fd = CreateFileAllowErrors(fs, filename);
EXPECT_GE(fd->fd(), 0) << "Opening file failed";
return fd; return fd;
} }
int FuseFstatTest::CreateFileReturnError(const TempTestFS *fs, const std::string &filename) { int FuseFstatTest::CreateFileReturnError(const TempTestFS *fs, const std::string &filename) {
int fd = CreateFileAllowErrors(fs, filename); auto fd = CreateFileAllowErrors(fs, filename);
if (fd >= 0) { return fd->errorcode();
return 0;
} else {
return -fd;
}
} }
int FuseFstatTest::CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename) { unique_ref<OpenFileHandle> FuseFstatTest::CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename) {
auto real_path = fs->mountDir() / filename; auto real_path = fs->mountDir() / filename;
int fd = ::open(real_path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); auto fd = make_unique_ref<OpenFileHandle>(real_path.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (fd >= 0) { return fd;
return fd;
} else {
return -errno;
}
} }
void FuseFstatTest::OnCreateAndOpenReturnFileDescriptor(const char *filename, int descriptor) { void FuseFstatTest::OnCreateAndOpenReturnFileDescriptor(const char *filename, int descriptor) {

View File

@ -3,14 +3,15 @@
#define MESSMER_FSPP_TEST_FUSE_FSTAT_TESTUTILS_FUSEFSTATTEST_H_ #define MESSMER_FSPP_TEST_FUSE_FSTAT_TESTUTILS_FUSEFSTATTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseFstatTest: public FuseTest { class FuseFstatTest: public FuseTest {
public: public:
int CreateFile(const TempTestFS *fs, const std::string &filename); cpputils::unique_ref<OpenFileHandle> CreateFile(const TempTestFS *fs, const std::string &filename);
int CreateFileReturnError(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: private:
int CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename); cpputils::unique_ref<OpenFileHandle> CreateFileAllowErrors(const TempTestFS *fs, const std::string &filename);
}; };

View File

@ -1,5 +1,8 @@
#include "FuseFsyncTest.h" #include "FuseFsyncTest.h"
using cpputils::unique_ref;
using cpputils::make_unique_ref;
void FuseFsyncTest::FsyncFile(const char *filename) { void FuseFsyncTest::FsyncFile(const char *filename) {
int error = FsyncFileReturnError(filename); int error = FsyncFileReturnError(filename);
EXPECT_EQ(0, error); EXPECT_EQ(0, error);
@ -8,8 +11,8 @@ void FuseFsyncTest::FsyncFile(const char *filename) {
int FuseFsyncTest::FsyncFileReturnError(const char *filename) { int FuseFsyncTest::FsyncFileReturnError(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); auto fd = OpenFile(fs.get(), filename);
int retval = ::fsync(fd); int retval = ::fsync(fd->fd());
if (retval == 0) { if (retval == 0) {
return 0; return 0;
} else { } else {
@ -17,9 +20,9 @@ int FuseFsyncTest::FsyncFileReturnError(const char *filename) {
} }
} }
int FuseFsyncTest::OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> FuseFsyncTest::OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDWR); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDWR);
EXPECT_GE(fd, 0) << "Error opening file"; EXPECT_GE(fd->fd(), 0) << "Error opening file";
return fd; return fd;
} }

View File

@ -3,6 +3,7 @@
#define MESSMER_FSPP_TEST_FUSE_FSYNC_TESTUTILS_FUSEFSYNCTEST_H_ #define MESSMER_FSPP_TEST_FUSE_FSYNC_TESTUTILS_FUSEFSYNCTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseFsyncTest: public FuseTest { class FuseFsyncTest: public FuseTest {
public: public:
@ -12,7 +13,7 @@ public:
int FsyncFileReturnError(const char *filename); int FsyncFileReturnError(const char *filename);
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename);
}; };
#endif #endif

View File

@ -1,5 +1,8 @@
#include "FuseFTruncateTest.h" #include "FuseFTruncateTest.h"
using cpputils::unique_ref;
using cpputils::make_unique_ref;
void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) { void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) {
int error = FTruncateFileReturnError(filename, size); int error = FTruncateFileReturnError(filename, size);
EXPECT_EQ(0, error); EXPECT_EQ(0, error);
@ -8,8 +11,8 @@ void FuseFTruncateTest::FTruncateFile(const char *filename, off_t size) {
int FuseFTruncateTest::FTruncateFileReturnError(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); auto fd = OpenFile(fs.get(), filename);
int retval = ::ftruncate(fd, size); int retval = ::ftruncate(fd->fd(), size);
if (0 == retval) { if (0 == retval) {
return 0; return 0;
} else { } else {
@ -17,9 +20,9 @@ int FuseFTruncateTest::FTruncateFileReturnError(const char *filename, off_t size
} }
} }
int FuseFTruncateTest::OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> FuseFTruncateTest::OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDWR); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDWR);
EXPECT_GE(fd, 0) << "Error opening file"; EXPECT_GE(fd->fd(), 0) << "Error opening file";
return fd; return fd;
} }

View File

@ -3,6 +3,7 @@
#define MESSMER_FSPP_TEST_FUSE_FTRUNCATE_TESTUTILS_FUSEFTRUNCATETEST_H_ #define MESSMER_FSPP_TEST_FUSE_FTRUNCATE_TESTUTILS_FUSEFTRUNCATETEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseFTruncateTest: public FuseTest { class FuseFTruncateTest: public FuseTest {
public: public:
@ -12,7 +13,7 @@ public:
int FTruncateFileReturnError(const char *filename, off_t size); int FTruncateFileReturnError(const char *filename, off_t size);
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename);
}; };
#endif #endif

View File

@ -5,21 +5,23 @@ using ::testing::StrEq;
using ::testing::WithParamInterface; using ::testing::WithParamInterface;
using ::testing::Values; using ::testing::Values;
using ::testing::Return; using ::testing::Return;
using cpputils::unique_ref;
using cpputils::make_unique_ref;
class FuseOpenFileDescriptorTest: public FuseOpenTest, public WithParamInterface<int> { class FuseOpenFileDescriptorTest: public FuseOpenTest, public WithParamInterface<int> {
public: public:
void OpenAndReadFile(const char *filename) { void OpenAndReadFile(const char *filename) {
auto fs = TestFS(); auto fs = TestFS();
int fd = OpenFile(fs.get(), filename); auto fd = OpenFile(fs.get(), filename);
ReadFile(fd); ReadFile(fd->fd());
} }
private: private:
int OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDONLY); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Opening file failed"; EXPECT_GE(fd->fd(), 0) << "Opening file failed";
return fd; return fd;
} }
void ReadFile(int fd) { void ReadFile(int fd) {

View File

@ -1,28 +1,21 @@
#include "FuseOpenTest.h" #include "FuseOpenTest.h"
int FuseOpenTest::OpenFile(const char *filename, int flags) { using cpputils::unique_ref;
int fd = OpenFileAllowError(filename, flags); using cpputils::make_unique_ref;
EXPECT_GE(fd, 0);
return fd; void FuseOpenTest::OpenFile(const char *filename, int flags) {
auto fs = TestFS();
auto fd = OpenFileAllowError(fs.get(), filename, flags);
EXPECT_GE(fd->fd(), 0);
} }
int FuseOpenTest::OpenFileReturnError(const char *filename, int flags) { 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 fs = TestFS();
auto fd = OpenFileAllowError(fs.get(), filename, flags);
auto realpath = fs->mountDir() / filename; return fd->errorcode();
int fd = ::open(realpath.c_str(), flags); }
if (fd >= 0) {
return fd; unique_ref<OpenFileHandle> FuseOpenTest::OpenFileAllowError(const TempTestFS *fs, const char *filename, int flags) {
} else { auto realpath = fs->mountDir() / filename;
return -errno; return make_unique_ref<OpenFileHandle>(realpath.c_str(), flags);
}
} }

View File

@ -3,15 +3,16 @@
#define MESSMER_FSPP_TEST_FUSE_OPENFILE_TESTUTILS_FUSEOPENTEST_H_ #define MESSMER_FSPP_TEST_FUSE_OPENFILE_TESTUTILS_FUSEOPENTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseOpenTest: public FuseTest { class FuseOpenTest: public FuseTest {
public: public:
const char *FILENAME = "/myfile"; const char *FILENAME = "/myfile";
int OpenFile(const char *FILENAME, int flags); void OpenFile(const char *FILENAME, int flags);
int OpenFileReturnError(const char *FILENAME, int flags); int OpenFileReturnError(const char *FILENAME, int flags);
private: private:
int OpenFileAllowError(const char *FILENAME, int flags); cpputils::unique_ref<OpenFileHandle> OpenFileAllowError(const TempTestFS *fs, const char *FILENAME, int flags);
}; };
MATCHER_P(OpenFlagsEq, expectedFlags, "") { MATCHER_P(OpenFlagsEq, expectedFlags, "") {

View File

@ -1,5 +1,8 @@
#include "FuseReadTest.h" #include "FuseReadTest.h"
using cpputils::make_unique_ref;
using cpputils::unique_ref;
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) {
auto retval = ReadFileReturnError(filename, buf, count, offset); auto retval = ReadFileReturnError(filename, buf, count, offset);
EXPECT_EQ(0, retval.error); EXPECT_EQ(0, retval.error);
@ -9,18 +12,18 @@ void FuseReadTest::ReadFile(const char *filename, void *buf, size_t count, off_t
FuseReadTest::ReadError FuseReadTest::ReadFileReturnError(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); auto fd = OpenFile(fs.get(), filename);
ReadError result; ReadError result;
errno = 0; errno = 0;
result.read_bytes = ::pread(fd, buf, count, offset); result.read_bytes = ::pread(fd->fd(), buf, count, offset);
result.error = errno; result.error = errno;
return result; return result;
} }
int FuseReadTest::OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> FuseReadTest::OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_RDONLY); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_RDONLY);
EXPECT_GE(fd, 0) << "Error opening file"; EXPECT_GE(fd->fd(), 0) << "Error opening file";
return fd; return fd;
} }

View File

@ -3,6 +3,7 @@
#define MESSMER_FSPP_TEST_FUSE_READ_TESTUTILS_FUSEREADTEST_H_ #define MESSMER_FSPP_TEST_FUSE_READ_TESTUTILS_FUSEREADTEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseReadTest: public FuseTest { class FuseReadTest: public FuseTest {
public: public:
@ -29,7 +30,7 @@ public:
} }
private: private:
int OpenFile(const TempTestFS *fs, const char *filename); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename);
}; };
#endif #endif

View File

@ -1,5 +1,8 @@
#include "FuseWriteTest.h" #include "FuseWriteTest.h"
using cpputils::unique_ref;
using cpputils::make_unique_ref;
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) {
auto retval = WriteFileReturnError(filename, buf, count, offset); auto retval = WriteFileReturnError(filename, buf, count, offset);
EXPECT_EQ(0, retval.error); EXPECT_EQ(0, retval.error);
@ -9,18 +12,18 @@ void FuseWriteTest::WriteFile(const char *filename, const void *buf, size_t coun
FuseWriteTest::WriteError FuseWriteTest::WriteFileReturnError(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); auto fd = OpenFile(fs.get(), filename);
WriteError result; WriteError result;
errno = 0; errno = 0;
result.written_bytes = ::pwrite(fd, buf, count, offset); result.written_bytes = ::pwrite(fd->fd(), buf, count, offset);
result.error = errno; result.error = errno;
return result; return result;
} }
int FuseWriteTest::OpenFile(const TempTestFS *fs, const char *filename) { unique_ref<OpenFileHandle> FuseWriteTest::OpenFile(const TempTestFS *fs, const char *filename) {
auto realpath = fs->mountDir() / filename; auto realpath = fs->mountDir() / filename;
int fd = ::open(realpath.c_str(), O_WRONLY); auto fd = make_unique_ref<OpenFileHandle>(realpath.c_str(), O_WRONLY);
EXPECT_GE(fd, 0) << "Error opening file"; EXPECT_GE(fd->fd(), 0) << "Error opening file";
return fd; return fd;
} }

View File

@ -3,6 +3,7 @@
#define MESSMER_FSPP_TEST_FUSE_WRITE_TESTUTILS_FUSEWRITETEST_H_ #define MESSMER_FSPP_TEST_FUSE_WRITE_TESTUTILS_FUSEWRITETEST_H_
#include "../../../testutils/FuseTest.h" #include "../../../testutils/FuseTest.h"
#include "../../../testutils/OpenFileHandle.h"
class FuseWriteTest: public FuseTest { class FuseWriteTest: public FuseTest {
public: public:
@ -17,7 +18,7 @@ public:
WriteError WriteFileReturnError(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); cpputils::unique_ref<OpenFileHandle> OpenFile(const TempTestFS *fs, const char *filename);
}; };
#endif #endif

View File

@ -0,0 +1 @@
#include "OpenFileHandle.h"

View File

@ -0,0 +1,45 @@
#pragma once
#ifndef MESSMER_FSPP_TEST_TESTUTILS_OPENFILEHANDLE_H_
#define MESSMER_FSPP_TEST_TESTUTILS_OPENFILEHANDLE_H_
#include <fcntl.h>
#include <unistd.h>
#include <cpp-utils/macros.h>
#include <errno.h>
#include <thread>
#include <chrono>
class OpenFileHandle final {
public:
OpenFileHandle(const char *path, int flags): fd_(::open(path, flags)), errno_(fd_ >= 0 ? 0 : errno) {
}
OpenFileHandle(const char *path, int flags, int flags2): fd_(::open(path, flags, flags2)), errno_(fd_ >= 0 ? 0 : errno) {
}
~OpenFileHandle() {
if (fd_ >= 0) {
::close(fd_);
#ifdef __APPLE__
// On Mac OS X, we might have to give it some time to free up the file
std::this_thread::sleep_for(std::chrono::milliseconds(50));
#endif
}
}
int fd() { return fd_; }
int errorcode() { return errno_; }
void release() {
fd_ = -1; // don't close anymore
}
private:
int fd_;
const int errno_;
DISALLOW_COPY_AND_ASSIGN(OpenFileHandle);
};
#endif