Tests for createAndOpenFile
This commit is contained in:
parent
6e0bda3689
commit
10142c2a36
@ -102,7 +102,6 @@ int fusepp_flush(const char *path, fuse_file_info *fileinfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int fusepp_fsync(const char *path, int datasync, fuse_file_info *fileinfo) {
|
int fusepp_fsync(const char *path, int datasync, fuse_file_info *fileinfo) {
|
||||||
printf("Fsync\n");fflush(stdout);
|
|
||||||
return FUSE_OBJ->fsync(bf::path(path), datasync, fileinfo);
|
return FUSE_OBJ->fsync(bf::path(path), datasync, fileinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ class Filesystem {
|
|||||||
public:
|
public:
|
||||||
virtual ~Filesystem() {}
|
virtual ~Filesystem() {}
|
||||||
|
|
||||||
|
virtual int createAndOpenFile(const boost::filesystem::path &path, mode_t mode) = 0;
|
||||||
virtual int openFile(const boost::filesystem::path &path, int flags) = 0;
|
virtual int openFile(const boost::filesystem::path &path, int flags) = 0;
|
||||||
virtual void flush(int descriptor) = 0;
|
virtual void flush(int descriptor) = 0;
|
||||||
virtual void closeFile(int descriptor) = 0;
|
virtual void closeFile(int descriptor) = 0;
|
||||||
@ -25,7 +26,6 @@ public:
|
|||||||
virtual void fsync(int descriptor) = 0;
|
virtual void fsync(int descriptor) = 0;
|
||||||
virtual void fdatasync(int descriptor) = 0;
|
virtual void fdatasync(int descriptor) = 0;
|
||||||
virtual void access(const boost::filesystem::path &path, int mask) = 0;
|
virtual void access(const boost::filesystem::path &path, int mask) = 0;
|
||||||
virtual int createAndOpenFile(const boost::filesystem::path &path, mode_t mode) = 0;
|
|
||||||
virtual void mkdir(const boost::filesystem::path &path, mode_t mode) = 0;
|
virtual void mkdir(const boost::filesystem::path &path, mode_t mode) = 0;
|
||||||
virtual void rmdir(const boost::filesystem::path &path) = 0;
|
virtual void rmdir(const boost::filesystem::path &path) = 0;
|
||||||
virtual void unlink(const boost::filesystem::path &path) = 0;
|
virtual void unlink(const boost::filesystem::path &path) = 0;
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
#include "testutils/FuseCreateAndOpenTest.h"
|
||||||
|
|
||||||
|
#include "fspp/impl/FuseErrnoException.h"
|
||||||
|
|
||||||
|
using ::testing::WithParamInterface;
|
||||||
|
using ::testing::Values;
|
||||||
|
using ::testing::Return;
|
||||||
|
using ::testing::Throw;
|
||||||
|
using ::testing::StrEq;
|
||||||
|
using ::testing::_;
|
||||||
|
|
||||||
|
using namespace fspp;
|
||||||
|
|
||||||
|
class FuseCreateAndOpenErrorTest: public FuseCreateAndOpenTest, public WithParamInterface<int> {
|
||||||
|
};
|
||||||
|
INSTANTIATE_TEST_CASE_P(FuseCreateAndOpenErrorTest, FuseCreateAndOpenErrorTest, 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(FuseCreateAndOpenErrorTest, ReturnNoError) {
|
||||||
|
ReturnDoesntExistOnLstat(FILENAME);
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq(FILENAME), _)).Times(1).WillOnce(Return(1));
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "testutils/FuseCreateAndOpenTest.h"
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::StrEq;
|
||||||
|
using ::testing::WithParamInterface;
|
||||||
|
using ::testing::Values;
|
||||||
|
using ::testing::Return;
|
||||||
|
|
||||||
|
class FuseCreateAndOpenFileDescriptorTest: public FuseCreateAndOpenTest, public WithParamInterface<int> {
|
||||||
|
public:
|
||||||
|
void CreateAndOpenAndReadFile(const char *filename) {
|
||||||
|
auto fs = TestFS();
|
||||||
|
|
||||||
|
int fd = CreateAndOpenFile(fs.get(), filename);
|
||||||
|
ReadFile(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int CreateAndOpenFile(const TempTestFS *fs, const char *filename) {
|
||||||
|
auto realpath = fs->mountDir() / filename;
|
||||||
|
int fd = ::open(realpath.c_str(), O_RDONLY | O_CREAT);
|
||||||
|
EXPECT_GE(fd, 0) << "Creating file failed";
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
void ReadFile(int fd) {
|
||||||
|
int retval = ::read(fd, nullptr, 0);
|
||||||
|
EXPECT_EQ(0, retval) << "Reading file failed";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
INSTANTIATE_TEST_CASE_P(FuseCreateAndOpenFileDescriptorTest, FuseCreateAndOpenFileDescriptorTest, Values(0, 2, 5, 1000, 1024*1024*1024));
|
||||||
|
|
||||||
|
TEST_P(FuseCreateAndOpenFileDescriptorTest, TestReturnedFileDescriptor) {
|
||||||
|
ReturnDoesntExistOnLstat(FILENAME);
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq(FILENAME), _))
|
||||||
|
.Times(1).WillOnce(Return(GetParam()));
|
||||||
|
EXPECT_CALL(fsimpl, read(GetParam(), _, _, _)).Times(1).WillOnce(Return(0));
|
||||||
|
//For the syscall to succeed, we also need to give an fstat implementation.
|
||||||
|
ReturnIsFileOnFstat(GetParam());
|
||||||
|
|
||||||
|
CreateAndOpenAndReadFile(FILENAME);
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
|
||||||
|
#include "testutils/FuseCreateAndOpenTest.h"
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::StrEq;
|
||||||
|
using ::testing::Return;
|
||||||
|
|
||||||
|
class FuseCreateAndOpenFilenameTest: public FuseCreateAndOpenTest {
|
||||||
|
public:
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(FuseCreateAndOpenFilenameTest, CreateAndOpenFile) {
|
||||||
|
ReturnDoesntExistOnLstat("/myfile");
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq("/myfile"), _))
|
||||||
|
.Times(1).WillOnce(Return(0));
|
||||||
|
//For the syscall to succeed, we also need to give an fstat implementation.
|
||||||
|
ReturnIsFileOnFstat(0);
|
||||||
|
|
||||||
|
CreateAndOpenFile("/myfile", O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FuseCreateAndOpenFilenameTest, CreateAndOpenFileNested) {
|
||||||
|
ReturnIsDirOnLstat("/mydir");
|
||||||
|
ReturnDoesntExistOnLstat("/mydir/myfile");
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq("/mydir/myfile"), _))
|
||||||
|
.Times(1).WillOnce(Return(0));
|
||||||
|
//For the syscall to succeed, we also need to give an fstat implementation.
|
||||||
|
ReturnIsFileOnFstat(0);
|
||||||
|
|
||||||
|
CreateAndOpenFile("/mydir/myfile", O_RDONLY);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(FuseCreateAndOpenFilenameTest, CreateAndOpenFileNested2) {
|
||||||
|
ReturnIsDirOnLstat("/mydir");
|
||||||
|
ReturnIsDirOnLstat("/mydir/mydir2");
|
||||||
|
ReturnDoesntExistOnLstat("/mydir/mydir2/myfile");
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq("/mydir/mydir2/myfile"), _))
|
||||||
|
.Times(1).WillOnce(Return(0));
|
||||||
|
//For the syscall to succeed, we also need to give an fstat implementation.
|
||||||
|
ReturnIsFileOnFstat(0);
|
||||||
|
|
||||||
|
CreateAndOpenFile("/mydir/mydir2/myfile", O_RDONLY);
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
#include "testutils/FuseCreateAndOpenTest.h"
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
using ::testing::StrEq;
|
||||||
|
using ::testing::WithParamInterface;
|
||||||
|
using ::testing::Values;
|
||||||
|
using ::testing::Return;
|
||||||
|
|
||||||
|
class FuseCreateAndOpenFlagsTest: public FuseCreateAndOpenTest, public WithParamInterface<unsigned int> {
|
||||||
|
};
|
||||||
|
INSTANTIATE_TEST_CASE_P(FuseCreateAndOpenFlagsTest, FuseCreateAndOpenFlagsTest, Values(O_RDWR, O_RDONLY, O_WRONLY));
|
||||||
|
|
||||||
|
//TODO Disabled because it doesn't seem to work. Fuse doesn't seem to pass flags to create(). Why?
|
||||||
|
TEST_P(FuseCreateAndOpenFlagsTest, DISABLED_testFlags) {
|
||||||
|
ReturnDoesntExistOnLstat(FILENAME);
|
||||||
|
EXPECT_CALL(fsimpl, createAndOpenFile(StrEq(FILENAME), OpenFlagsEq(GetParam())))
|
||||||
|
.Times(1).WillOnce(Return(0));
|
||||||
|
//For the syscall to succeed, we also need to give an fstat implementation.
|
||||||
|
ReturnIsFileOnFstat(0);
|
||||||
|
|
||||||
|
CreateAndOpenFile(FILENAME, GetParam());
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
#include "FuseCreateAndOpenTest.h"
|
||||||
|
|
||||||
|
using ::testing::_;
|
||||||
|
|
||||||
|
int FuseCreateAndOpenTest::CreateAndOpenFile(const char *filename, int flags) {
|
||||||
|
int fd = CreateAndOpenFileAllowError(filename, flags);
|
||||||
|
EXPECT_GE(fd, 0);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FuseCreateAndOpenTest::ReturnIsFileOnFstat(int descriptor) {
|
||||||
|
EXPECT_CALL(fsimpl, fstat(descriptor, _)).WillRepeatedly(ReturnIsFileFstat);
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef TEST_FSPP_FUSE_OPENFILE_TESTUTILS_FUSECREATEANDOPENTEST_H_
|
||||||
|
#define TEST_FSPP_FUSE_OPENFILE_TESTUTILS_FUSECREATEANDOPENTEST_H_
|
||||||
|
|
||||||
|
#include "test/testutils/FuseTest.h"
|
||||||
|
|
||||||
|
class FuseCreateAndOpenTest: public FuseTest {
|
||||||
|
public:
|
||||||
|
const char *FILENAME = "/myfile";
|
||||||
|
|
||||||
|
int CreateAndOpenFile(const char *FILENAME, int flags);
|
||||||
|
int CreateAndOpenFileAllowError(const char *FILENAME, int flags);
|
||||||
|
void ReturnIsFileOnFstat(int descriptor);
|
||||||
|
};
|
||||||
|
|
||||||
|
MATCHER_P(OpenFlagsEq, expectedFlags, "") {
|
||||||
|
printf("%d vs %d\n", expectedFlags, O_ACCMODE & arg);
|
||||||
|
return expectedFlags == (O_ACCMODE & arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user