Use FUSE_STAT on Dokan

This commit is contained in:
Sebastian Messmer 2018-09-15 18:02:03 -07:00
parent 61451069e8
commit a866fda3a9
20 changed files with 117 additions and 86 deletions

View File

@ -11,6 +11,7 @@
#else
#include <sys/statvfs.h>
#endif
#include "stat_compatibility.h"
namespace fspp {
namespace fuse {
@ -23,8 +24,8 @@ public:
virtual int openFile(const boost::filesystem::path &path, int flags) = 0;
virtual void flush(int descriptor) = 0;
virtual void closeFile(int descriptor) = 0;
virtual void lstat(const boost::filesystem::path &path, struct ::stat *stbuf) = 0;
virtual void fstat(int descriptor, struct ::stat *stbuf) = 0;
virtual void lstat(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf) = 0;
virtual void fstat(int descriptor, fspp::fuse::STAT *stbuf) = 0;
//TODO Test chmod
virtual void chmod(const boost::filesystem::path &path, ::mode_t mode) = 0;
//TODO Test chown

View File

@ -31,12 +31,12 @@ bool is_valid_fspp_path(const bf::path& path) {
//#define FSPP_LOG 1
namespace {
int fusepp_getattr(const char *path, struct stat *stbuf) {
int fusepp_getattr(const char *path, fspp::fuse::STAT *stbuf) {
int rs = FUSE_OBJ->getattr(bf::path(path), stbuf);
return rs;
}
int fusepp_fgetattr(const char *path, struct stat *stbuf, fuse_file_info *fileinfo) {
int fusepp_fgetattr(const char *path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo) {
return FUSE_OBJ->fgetattr(bf::path(path), stbuf, fileinfo);
}
@ -309,7 +309,7 @@ void Fuse::stop() {
}
}
int Fuse::getattr(const bf::path &path, struct stat *stbuf) {
int Fuse::getattr(const bf::path &path, fspp::fuse::STAT *stbuf) {
#ifdef FSPP_LOG
LOG(DEBUG, "getattr({}, _, _)", path);
#endif
@ -331,7 +331,7 @@ int Fuse::getattr(const bf::path &path, struct stat *stbuf) {
}
}
int Fuse::fgetattr(const bf::path &path, struct stat *stbuf, fuse_file_info *fileinfo) {
int Fuse::fgetattr(const bf::path &path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo) {
#ifdef FSPP_LOG
LOG(DEBUG, "fgetattr({}, _, _)\n", path);
#endif
@ -801,7 +801,7 @@ int Fuse::readdir(const bf::path &path, void *buf, fuse_fill_dir_t filler, int64
try {
ASSERT(is_valid_fspp_path(path), "has to be an absolute path");
auto entries = _fs->readDir(path);
struct stat stbuf{};
fspp::fuse::STAT stbuf{};
for (const auto &entry : *entries) {
//We could pass more file metadata to filler() in its third parameter,
//but it doesn't help performance since fuse ignores everything in stbuf

View File

@ -11,6 +11,7 @@
#include <boost/optional.hpp>
#include <cpp-utils/macros.h>
#include <atomic>
#include "stat_compatibility.h"
namespace fspp {
class Device;
@ -27,8 +28,8 @@ public:
bool running() const;
void stop();
int getattr(const boost::filesystem::path &path, struct stat *stbuf);
int fgetattr(const boost::filesystem::path &path, struct stat *stbuf, fuse_file_info *fileinfo);
int getattr(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf);
int fgetattr(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf, fuse_file_info *fileinfo);
int readlink(const boost::filesystem::path &path, char *buf, size_t size);
int mknod(const boost::filesystem::path &path, ::mode_t mode, dev_t rdev);
int mkdir(const boost::filesystem::path &path, ::mode_t mode);

View File

@ -7,6 +7,8 @@
#include <fuse.h>
#elif __APPLE__
#include <osxfuse/fuse.h>
#elif defined(_MSC_VER)
#include <fuse.h> // Dokany fuse
#else
#error System not supported
#endif

View File

@ -0,0 +1,27 @@
#pragma once
#ifndef MESSMER_FSPP_FUSE_STATCOMPATIBILITY_H
#define MESSMER_FSPP_FUSE_STATCOMPATIBILITY_H
namespace fspp {
namespace fuse {
// Dokan has a different "struct stat" called "fspp::fuse::STAT", but it's compatible.
// To make our code work with both, we use "STAT" everywhere instead of "stat"
// and define it here to the correct type
#if defined(_MSC_VER)
#include <fuse.h>
typedef struct FUSE_STAT STAT;
#else
#include <sys/stat.h>
typedef struct ::stat STAT;
#endif
}
}
#endif

View File

@ -139,7 +139,7 @@ void FilesystemImpl::closeFile(int descriptor) {
}
namespace {
void convert_stat_info_(const fspp::Node::stat_info& input, struct ::stat *output) {
void convert_stat_info_(const fspp::Node::stat_info& input, fspp::fuse::STAT *output) {
output->st_nlink = input.nlink;
output->st_mode = input.mode.value();
output->st_uid = input.uid.value();
@ -152,7 +152,7 @@ void convert_stat_info_(const fspp::Node::stat_info& input, struct ::stat *outpu
}
}
void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
void FilesystemImpl::lstat(const bf::path &path, fspp::fuse::STAT *stbuf) {
PROFILE(_lstatNanosec);
auto node = _device->Load(path);
if(node == none) {
@ -163,7 +163,7 @@ void FilesystemImpl::lstat(const bf::path &path, struct ::stat *stbuf) {
}
}
void FilesystemImpl::fstat(int descriptor, struct ::stat *stbuf) {
void FilesystemImpl::fstat(int descriptor, fspp::fuse::STAT *stbuf) {
PROFILE(_fstatNanosec);
auto stat_info = _open_files.get(descriptor)->stat();
convert_stat_info_(stat_info, stbuf);

View File

@ -27,8 +27,8 @@ public:
int openFile(const boost::filesystem::path &path, int flags) override;
void flush(int descriptor) override;
void closeFile(int descriptor) override;
void lstat(const boost::filesystem::path &path, struct ::stat *stbuf) override;
void fstat(int descriptor, struct ::stat *stbuf) override;
void lstat(const boost::filesystem::path &path, fspp::fuse::STAT *stbuf) override;
void fstat(int descriptor, fspp::fuse::STAT *stbuf) override;
void chmod(const boost::filesystem::path &path, ::mode_t mode) override;
void chown(const boost::filesystem::path &path, ::uid_t uid, ::gid_t gid) override;
void truncate(const boost::filesystem::path &path, fspp::num_bytes_t size) override;

View File

@ -6,7 +6,7 @@ using ::testing::Values;
class FuseLstatReturnATimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
private:
void set(struct stat *stat, time_t value) override {
void set(fspp::fuse::STAT *stat, time_t value) override {
stat->st_atim.tv_sec = value;
stat->st_atim.tv_nsec = 0;
}
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnATimeTest, FuseLstatReturnATimeTest, Valu
));
TEST_P(FuseLstatReturnATimeTest, ReturnedFileAtimeIsCorrect) {
struct ::stat result = CallFileLstatWithValue(GetParam());
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
EXPECT_EQ(0, result.st_atim.tv_nsec);
}
TEST_P(FuseLstatReturnATimeTest, ReturnedDirAtimeIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_atim.tv_sec);
EXPECT_EQ(0, result.st_atim.tv_nsec);
}

View File

@ -6,7 +6,7 @@ using ::testing::Values;
class FuseLstatReturnCtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
private:
void set(struct stat *stat, time_t value) override {
void set(fspp::fuse::STAT *stat, time_t value) override {
stat->st_ctim.tv_sec = value;
stat->st_ctim.tv_nsec = 0;
}
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnCtimeTest, FuseLstatReturnCtimeTest, Valu
));
TEST_P(FuseLstatReturnCtimeTest, ReturnedFileCtimeIsCorrect) {
struct ::stat result = CallFileLstatWithValue(GetParam());
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
EXPECT_EQ(0, result.st_ctim.tv_nsec);
}
TEST_P(FuseLstatReturnCtimeTest, ReturnedDirCtimeIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_ctim.tv_sec);
EXPECT_EQ(0, result.st_ctim.tv_nsec);
}

View File

@ -5,7 +5,7 @@ using ::testing::Values;
class FuseLstatReturnGidTest: public FuseLstatReturnTest<gid_t>, public WithParamInterface<gid_t> {
private:
void set(struct stat *stat, gid_t value) override {
void set(fspp::fuse::STAT *stat, gid_t value) override {
stat->st_gid = value;
}
};
@ -15,11 +15,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnGidTest, FuseLstatReturnGidTest, Values(
));
TEST_P(FuseLstatReturnGidTest, ReturnedFileGidIsCorrect) {
struct ::stat result = CallFileLstatWithValue(GetParam());
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_gid);
}
TEST_P(FuseLstatReturnGidTest, ReturnedDirGidIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_gid);
}

View File

@ -5,8 +5,8 @@ using ::testing::Values;
class FuseLstatReturnModeTest: public FuseLstatTest, public WithParamInterface<mode_t> {
public:
struct stat CallLstatWithValue(mode_t mode) {
return CallLstatWithImpl([mode] (struct stat *stat) {
fspp::fuse::STAT CallLstatWithValue(mode_t mode) {
return CallLstatWithImpl([mode] (fspp::fuse::STAT *stat) {
stat->st_mode = mode;
});
}
@ -19,6 +19,6 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnModeTest, FuseLstatReturnModeTest, Values
));
TEST_P(FuseLstatReturnModeTest, ReturnedModeIsCorrect) {
struct ::stat result = CallLstatWithValue(GetParam());
fspp::fuse::STAT result = CallLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_mode);
}

View File

@ -6,7 +6,7 @@ using ::testing::Values;
class FuseLstatReturnMtimeTest: public FuseLstatReturnTest<time_t>, public WithParamInterface<time_t> {
private:
void set(struct stat *stat, time_t value) override {
void set(fspp::fuse::STAT *stat, time_t value) override {
stat->st_mtim.tv_sec = value;
stat->st_mtim.tv_nsec = 0;
}
@ -19,13 +19,13 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnMtimeTest, FuseLstatReturnMtimeTest, Valu
));
TEST_P(FuseLstatReturnMtimeTest, ReturnedFileMtimeIsCorrect) {
struct ::stat result = CallFileLstatWithValue(GetParam());
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
EXPECT_EQ(0, result.st_mtim.tv_nsec);
}
TEST_P(FuseLstatReturnMtimeTest, ReturnedDirMtimeIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_mtim.tv_sec);
EXPECT_EQ(0, result.st_mtim.tv_nsec);
}

View File

@ -5,7 +5,7 @@ using ::testing::Values;
class FuseLstatReturnNlinkTest: public FuseLstatReturnTest<nlink_t>, public WithParamInterface<nlink_t> {
private:
void set(struct stat *stat, nlink_t value) override {
void set(fspp::fuse::STAT *stat, nlink_t value) override {
stat->st_nlink = value;
}
};
@ -17,12 +17,12 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnNlinkTest, FuseLstatReturnNlinkTest, Valu
));
TEST_P(FuseLstatReturnNlinkTest, ReturnedFileNlinkIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_nlink);
}
TEST_P(FuseLstatReturnNlinkTest, ReturnedDirNlinkIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_nlink);
}

View File

@ -5,7 +5,7 @@ using ::testing::Values;
class FuseLstatReturnSizeTest: public FuseLstatReturnTest<fspp::num_bytes_t>, public WithParamInterface<fspp::num_bytes_t> {
private:
void set(struct stat *stat, fspp::num_bytes_t value) override {
void set(fspp::fuse::STAT *stat, fspp::num_bytes_t value) override {
stat->st_size = value.value();
}
};
@ -17,11 +17,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnSizeTest, FuseLstatReturnSizeTest, Values
));
TEST_P(FuseLstatReturnSizeTest, ReturnedFileSizeIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
}
TEST_P(FuseLstatReturnSizeTest, ReturnedDirSizeIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), fspp::num_bytes_t(result.st_size));
}

View File

@ -5,7 +5,7 @@ using ::testing::Values;
class FuseLstatReturnUidTest: public FuseLstatReturnTest<uid_t>, public WithParamInterface<uid_t> {
private:
void set(struct stat *stat, uid_t value) override {
void set(fspp::fuse::STAT *stat, uid_t value) override {
stat->st_uid = value;
}
};
@ -15,11 +15,11 @@ INSTANTIATE_TEST_CASE_P(FuseLstatReturnUidTest, FuseLstatReturnUidTest, Values(
));
TEST_P(FuseLstatReturnUidTest, ReturnedFileUidIsCorrect) {
struct ::stat result = CallFileLstatWithValue(GetParam());
fspp::fuse::STAT result = CallFileLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_uid);
}
TEST_P(FuseLstatReturnUidTest, ReturnedDirUidIsCorrect) {
struct ::stat result = CallDirLstatWithValue(GetParam());
fspp::fuse::STAT result = CallDirLstatWithValue(GetParam());
EXPECT_EQ(GetParam(), result.st_uid);
}

View File

@ -4,37 +4,37 @@
#include "FuseLstatTest.h"
// This class offers test helpers for testing (struct stat) entries. We return them from
// This class offers test helpers for testing (fspp::fuse::STAT) entries. We return them from
// our mock filesystem, set up a temporary filesystem, call lstat syscall on it, and
// then check the return value.
template<typename Property>
class FuseLstatReturnTest: public FuseLstatTest {
public:
// Set the specified (struct stat) entry to the given value, and test whether it is correctly returned from the syscall.
// Set the specified (fspp::fuse::STAT) entry to the given value, and test whether it is correctly returned from the syscall.
// The CallFile[...] version tests it on a file node of the filesystem, the CallDir[...] version on a dir node.
struct stat CallFileLstatWithValue(Property value);
struct stat CallDirLstatWithValue(Property value);
fspp::fuse::STAT CallFileLstatWithValue(Property value);
fspp::fuse::STAT CallDirLstatWithValue(Property value);
private:
std::function<void(struct stat*)> SetPropertyImpl(Property value);
std::function<void(fspp::fuse::STAT*)> SetPropertyImpl(Property value);
// Override this function to specify, how to set the specified (struct stat) entry on the passed (struct stat *) object.
virtual void set(struct stat *stat, Property value) = 0;
// Override this function to specify, how to set the specified (fspp::fuse::STAT) entry on the passed (fspp::fuse::STAT *) object.
virtual void set(fspp::fuse::STAT *stat, Property value) = 0;
};
template<typename Property>
struct stat FuseLstatReturnTest<Property>::CallFileLstatWithValue(Property value) {
FUSE_STAT FuseLstatReturnTest<Property>::CallFileLstatWithValue(Property value) {
return CallFileLstatWithImpl(SetPropertyImpl(value));
}
template<typename Property>
struct stat FuseLstatReturnTest<Property>::CallDirLstatWithValue(Property value) {
FUSE_STAT FuseLstatReturnTest<Property>::CallDirLstatWithValue(Property value) {
return CallDirLstatWithImpl(SetPropertyImpl(value));
}
template<typename Property>
std::function<void(struct stat*)> FuseLstatReturnTest<Property>::SetPropertyImpl(Property value) {
return [this, value] (struct stat *stat) {
std::function<void(fspp::fuse::STAT*)> FuseLstatReturnTest<Property>::SetPropertyImpl(Property value) {
return [this, value] (fspp::fuse::STAT *stat) {
set(stat, value);
};
}

View File

@ -6,21 +6,21 @@ using ::testing::_;
using ::testing::Invoke;
void FuseLstatTest::LstatPath(const std::string &path) {
struct stat dummy{};
fspp::fuse::STAT dummy{};
LstatPath(path, &dummy);
}
int FuseLstatTest::LstatPathReturnError(const std::string &path) {
struct stat dummy{};
fspp::fuse::STAT dummy{};
return LstatPathReturnError(path, &dummy);
}
void FuseLstatTest::LstatPath(const std::string &path, struct stat *result) {
void FuseLstatTest::LstatPath(const std::string &path, fspp::fuse::STAT *result) {
int error = LstatPathReturnError(path, result);
EXPECT_EQ(0, error) << "lstat syscall failed. errno: " << error;
}
int FuseLstatTest::LstatPathReturnError(const std::string &path, struct stat *result) {
int FuseLstatTest::LstatPathReturnError(const std::string &path, fspp::fuse::STAT *result) {
auto fs = TestFS();
auto realpath = fs->mountDir() / path;
@ -32,27 +32,27 @@ int FuseLstatTest::LstatPathReturnError(const std::string &path, struct stat *re
}
}
struct stat FuseLstatTest::CallFileLstatWithImpl(function<void(struct stat*)> implementation) {
fspp::fuse::STAT FuseLstatTest::CallFileLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
return CallLstatWithModeAndImpl(S_IFREG, implementation);
}
struct stat FuseLstatTest::CallDirLstatWithImpl(function<void(struct stat*)> implementation) {
fspp::fuse::STAT FuseLstatTest::CallDirLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
return CallLstatWithModeAndImpl(S_IFDIR, implementation);
}
struct stat FuseLstatTest::CallLstatWithImpl(function<void(struct stat*)> implementation) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).WillRepeatedly(Invoke([implementation](const char*, struct ::stat *stat) {
fspp::fuse::STAT FuseLstatTest::CallLstatWithImpl(function<void(fspp::fuse::STAT*)> implementation) {
EXPECT_CALL(fsimpl, lstat(StrEq(FILENAME), _)).WillRepeatedly(Invoke([implementation](const char*, fspp::fuse::STAT *stat) {
implementation(stat);
}));
struct stat result{};
fspp::fuse::STAT result{};
LstatPath(FILENAME, &result);
return result;
}
struct stat FuseLstatTest::CallLstatWithModeAndImpl(mode_t mode, function<void(struct stat*)> implementation) {
return CallLstatWithImpl([mode, implementation] (struct stat *stat) {
fspp::fuse::STAT FuseLstatTest::CallLstatWithModeAndImpl(mode_t mode, function<void(fspp::fuse::STAT*)> implementation) {
return CallLstatWithImpl([mode, implementation] (fspp::fuse::STAT *stat) {
stat->st_mode = mode;
implementation(stat);
});

View File

@ -17,27 +17,27 @@ protected:
// and call the lstat syscall on the given (filesystem-relative) path.
void LstatPath(const std::string &path);
// Same as LstatPath above, but also return the result of the lstat syscall.
void LstatPath(const std::string &path, struct stat *result);
void LstatPath(const std::string &path, fspp::fuse::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 value of errno after calling ::lstat.
int LstatPathReturnError(const std::string &path);
int LstatPathReturnError(const std::string &path, struct stat *result);
int LstatPathReturnError(const std::string &path, fspp::fuse::STAT *result);
// You can specify an implementation, which can modify the (struct stat *) result,
// You can specify an implementation, which can modify the (fspp::fuse::STAT *) result,
// our fuse mock filesystem implementation will then return this to fuse on an lstat call.
// This functions then set up a temporary filesystem with this mock, call lstat on a filesystem node
// and return the (struct stat) returned from an lstat syscall to this filesystem.
struct stat CallLstatWithImpl(std::function<void(struct stat*)> implementation);
// and return the (fspp::fuse::STAT) returned from an lstat syscall to this filesystem.
fspp::fuse::STAT CallLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
// These two functions are like CallLstatWithImpl, but they also modify the (struct stat).st_mode
// These two functions are like CallLstatWithImpl, but they also modify the (fspp::fuse::STAT).st_mode
// field, so the node accessed is specified to be a file/directory.
struct stat CallFileLstatWithImpl(std::function<void(struct stat*)> implementation);
struct stat CallDirLstatWithImpl(std::function<void(struct stat*)> implementation);
fspp::fuse::STAT CallFileLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
fspp::fuse::STAT CallDirLstatWithImpl(std::function<void(fspp::fuse::STAT*)> implementation);
private:
struct stat CallLstatWithModeAndImpl(mode_t mode, std::function<void(struct stat*)> implementation);
fspp::fuse::STAT CallLstatWithModeAndImpl(mode_t mode, std::function<void(fspp::fuse::STAT*)> implementation);
};
#endif

View File

@ -65,8 +65,8 @@ const bf::path &FuseTest::TempTestFS::mountDir() const {
return _mountDir.path();
}
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFileWithSize(fspp::num_bytes_t size) {
return Invoke([size](const char*, struct ::stat* result) {
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsFileWithSize(fspp::num_bytes_t size) {
return Invoke([size](const char*, fspp::fuse::STAT* result) {
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
result->st_nlink = 1;
result->st_size = size.value();
@ -74,15 +74,15 @@ Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFileWithSize(fspp::n
}
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsFile = ReturnIsFileWithSize(fspp::num_bytes_t(0));
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsFile = ReturnIsFileWithSize(fspp::num_bytes_t(0));
Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstat =
Invoke([](int, struct ::stat* result) {
Action<void(int, fspp::fuse::STAT*)> FuseTest::ReturnIsFileFstat =
Invoke([](int, fspp::fuse::STAT* result) {
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
result->st_nlink = 1;
});
Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_bytes_t size) {
Action<void(int, fspp::fuse::STAT*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_bytes_t size) {
return Invoke([size](int, struct ::stat *result) {
result->st_mode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
result->st_nlink = 1;
@ -91,13 +91,13 @@ Action<void(int, struct ::stat*)> FuseTest::ReturnIsFileFstatWithSize(fspp::num_
});
}
Action<void(const char*, struct ::stat*)> FuseTest::ReturnIsDir =
Invoke([](const char*, struct ::stat* result) {
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnIsDir =
Invoke([](const char*, fspp::fuse::STAT* result) {
result->st_mode = S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH | S_IXUSR | S_IXGRP | S_IXOTH;
result->st_nlink = 1;
});
Action<void(const char*, struct ::stat*)> FuseTest::ReturnDoesntExist = Throw(fspp::fuse::FuseErrnoException(ENOENT));
Action<void(const char*, fspp::fuse::STAT*)> FuseTest::ReturnDoesntExist = Throw(fspp::fuse::FuseErrnoException(ENOENT));
void FuseTest::OnOpenReturnFileDescriptor(const char *filename, int descriptor) {
EXPECT_CALL(fsimpl, openFile(StrEq(filename), _)).Times(1).WillOnce(Return(descriptor));

View File

@ -46,8 +46,8 @@ public:
MOCK_PATH_METHOD2(openFile, int, int);
MOCK_METHOD1(closeFile, void(int));
MOCK_PATH_METHOD2(lstat, void, struct ::stat*);
MOCK_METHOD2(fstat, void(int, struct ::stat*));
MOCK_PATH_METHOD2(lstat, void, fspp::fuse::STAT*);
MOCK_METHOD2(fstat, void(int, fspp::fuse::STAT*));
MOCK_PATH_METHOD2(truncate, void, fspp::num_bytes_t);
MOCK_METHOD2(ftruncate, void(int, fspp::num_bytes_t));
MOCK_METHOD4(read, fspp::num_bytes_t(int, void*, fspp::num_bytes_t, fspp::num_bytes_t));
@ -106,12 +106,12 @@ public:
//TODO Combine ReturnIsFile and ReturnIsFileFstat. This should be possible in gmock by either (a) using ::testing::Undefined as parameter type or (b) using action macros
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsFile;
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsFileWithSize(fspp::num_bytes_t size);
static ::testing::Action<void(int, struct ::stat*)> ReturnIsFileFstat;
static ::testing::Action<void(int, struct ::stat*)> ReturnIsFileFstatWithSize(fspp::num_bytes_t size);
static ::testing::Action<void(const char*, struct ::stat*)> ReturnIsDir;
static ::testing::Action<void(const char*, struct ::stat*)> ReturnDoesntExist;
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsFile;
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsFileWithSize(fspp::num_bytes_t size);
static ::testing::Action<void(int, fspp::fuse::STAT*)> ReturnIsFileFstat;
static ::testing::Action<void(int, fspp::fuse::STAT*)> ReturnIsFileFstatWithSize(fspp::num_bytes_t size);
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnIsDir;
static ::testing::Action<void(const char*, fspp::fuse::STAT*)> ReturnDoesntExist;
void ReturnIsFileOnLstat(const boost::filesystem::path &path);
void ReturnIsFileOnLstatWithSize(const boost::filesystem::path &path, fspp::num_bytes_t size);